String Arrays not returning expected value - java

I'm very new to Java but this has had me stumped for the last half an hour or so. I'm reading in lines from a text file and storing them as String Arrays. From here I'm trying to use the values from within the arrays to be used to initialise another class I have. To initialise my Route class (hence using routeName) I need to take the first value from the array and pass it as a string. When I try to return s[0] for routeName, I'm given the last line of from my text file. Any ideas on how to fix this would be greatly appreciated. I'm in the process of testing still so thats why my code is barely finished.
My text file is as follows.
66
Uq Lakes, Southbank
1,2,3,4,5
2,3,4,5,6
and my code:
import java.io.*;
import java.util.*;
public class Scan {
public static void main(String args[]) throws IOException {
String routeName = "";
String stationName = " ";
Scanner timetable = new Scanner(new File("fileName.txt"));
while (timetable.hasNextLine()) {
String[] s = timetable.nextLine().split("\n");
routeName = s[0];
}
System.out.println(routeName);
}
}

The method you are calling timetable.nextLine.split("\n") will return the Array of String.
So every time when you call this method is overwrites your array with new line in file and as the last line is added finally in your array you are getting the lat line at the end.
below is the code you can use.
public static void main(String[] args) throws FileNotFoundException {
String routeName = "";
Scanner timetable;
int count = 0;
String[] s = new String[10];
timetable = new Scanner(new File("fileName.txt"));
while (timetable.hasNextLine()) {
String line = timetable.nextLine();
s[count++] = line;
}
routeName = s[0];
System.out.println(routeName);
}

Scanner.nextLine() returns a single line so splitting by '\n' will always give a single element array, e.g.:
timetable.nextLine().split("\n"); // e.g., "1,2,3,4,5" => ["1,2,3,4,5"]
Try splitting by the ',' instead, e.g.:
timetable.nextLine().split(","); // e.g., "1,2,3,4,5" => ["1", "2", "3", "4", "5"]
NOTE: If you are intending for the array to contain individual lines, then check out this SO post.
Scanner s = new Scanner(new File(filename));
List<String> lines = new ArrayList<String>(); // A List can be dynamically resized
while(s.hasNextLine()) lines.add(s.nextLine()); // Store each line in the list
String[] arr = lines.toArray(new String[0]); // If you really need an Array, use this

Your while loop itterates over all lines and sets the current line to the routeName. Thats why you habe the last line in you string. What you could do is calling a break, when you habe read the first line oft the file. Then you will have the first line.

Related

How to limit the number of words when reading a line from standard input?

I am new to Stackoverflow and this is my first time asking a question. I have searched my problem thoroughly, however, could not find an appropriate answer. I am sorry if this has been asked. Thank you in advance.
The question is from Hyperskill.com as follows:
Write a program that reads five words from the standard input and outputs each word in a new line.
First, you need to print all the words from the first line, then from the second (from the left to right).
Sample Input 1:
This Java course
is adaptive
Sample Output 1:
This
Java
course
is
adaptive
My trial to solve it
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
/* I have not initialized the "userInput" String.
* I know that String is immutable in Java and
* if I initialize it to an empty String ""
* and read a String from user.
* It will not overwrite to the "userInput" String.
* But create another String object to give it the value of the user input,
* and references the new String object to "userInput".
* I didn't want to waste memory like that.
*/
String userInput;
String[] userInputSplitFirstLine = new String[3];
String[] userInputSplitSecondLine = new String[2];
Scanner scan = new Scanner(System.in);
userInput = scan.nextLine();
userInputSplitFirstLine = userInput.split("\\s+");
userInput = scan.nextLine();
userInputSplitSecondLine = userInput.split("\\s+");
for(String firstLineSplitted: userInputSplitFirstLine) {
System.out.println(firstLineSplitted);
}
for(String secondLineSplitted: userInputSplitSecondLine) {
System.out.println(secondLineSplitted);
}
scan.close();
}
}
If you try the sample input above, the output will match the sample output above. However, if you write more than 3 words to the first line and/or more than 2 words to the second line, the userInputSplitFirstLine array of size 3 will store more than 3 words. Same goes with the userInputSplitSecondLine array also. My first question is how can an array of size 3 (userInputSplitFirstLine) and an array of size 2 (userInputSplitSecondLine) can hold more than 3 and 2 elements, respectively? My second question is that how can I restrict/limit the number of words that the user can insert in a line; for example, the first line only accepts 3 words and the second line only accepts 2 words?
Also the answer to this question suggested by Hyperskill.com is as follows:
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String wordOne = scanner.next();
String wordTwo = scanner.next();
String wordThree = scanner.next();
String wordFour = scanner.next();
String wordFive = scanner.next();
System.out.println(wordOne);
System.out.println(wordTwo);
System.out.println(wordThree);
System.out.println(wordFour);
System.out.println(wordFive);
}
}
You can use next method of scanner object to read string and then it can be printed easily on new line.
while(true){
if(scanner.hasNext()){
System.out.println(scanner.next());
}
else{
break;
}
}
I think this should do the work. Don't hesitate to ask, if you have some questions.
import java.util.Scanner;
class App {
public static void main(String[] args) {
final StringBuffer line = new StringBuffer();
final StringBuffer words = new StringBuffer();
try (final Scanner sc = new Scanner(System.in)) {
while (sc.hasNextLine()) {
final String currentLine = sc.nextLine();
line.append(currentLine).append(System.lineSeparator());
for (final String word : currentLine.split("\\s+")) {
words.append(word).append(System.lineSeparator());
}
}
} finally {
System.out.println(line.toString());
System.out.println();
System.out.println(words.toString());
}
}
}
My first question is how can an array of size 3 (userInputSplitFirstLine) and an array of size 2 (userInputSplitSecondLine) can hold more than 3 and 2 elements, respectively?
The array here:
String[] userInputSplitFirstLine = new String[3];
is not the same one as the one you got from split:
userInputSplitFirstLine = userInput.split("\\s+");
When you do the above assignment, the old array that was in there is basically "overwritten", and now userInputSplitFirstLine refers to this new array that has a length independent of what the old array had. split always return a new array.
My second question is that how can I restrict/limit the number of words that the user can insert in a line; for example, the first line only accepts 3 words and the second line only accepts 2 words?
It really depends on what you mean by "restrict". If you just want to check if there are exactly three words, and if not, exit the program, you can do this:
userInputSplitFirstLine = userInput.split("\\s+");
if (userInputSplitFirstLine.length != 3) {
System.out.println("Please enter exactly 3 words!");
return;
}
You can do something similar with the second line.
If you want the user to be unable to type more than 3 words, then that's impossible, because this is a command line app.
By the way, the code in the suggested solution works because next() returns the next "word" (or what we generally think of as a word, anyway) by default.
hope this will help you!
public class pratice1 {
public static void main (String[]args) {
Scanner sc = new Scanner(System.in);
String input = sc.nextLine();
String input1 = sc.nextLine();
char[]a =input.toCharArray();
char[]a1 = input1.toCharArray();
System.out.println(input +""+ input1);
int a2=0;
if(input!=null) {
for(int i=0;i<input.length();i++) {
if(a[i]==' ') {
a2=i;
for(int j=0;j<a2;j++) {
System.out.println(a[i]);
a2=0;
}
}
else System.out.print(a[i]);
}System.out.println("");
for(int i=0;i<input1.length();i++) {
if(a1[i]==' ') {
a2=i;
for(int j=0;j<a2;j++) {
System.out.println(a1[i]);
a2=0;
}
}
else System.out.print(a1[i]);
}
}
}
}
To solve the problem:
Write a program that reads five words from the standard input and
outputs each word in a new line.
This was my solution:
while(scanner.hasNext()){
System.out.println(scanner.next());
}

searching for words in a text file in java

I am trying to search for words within a text file and replace all upper-cased with lower-cased characters. The problem is that when I use the replace All function using a regular expression I get a syntax error. I have tried different tactics, but it doesn't work. Any tips? I think that maybe I should create a replace All method that I would have to invoke, but I don't really see its use.
public static void main() throws FileNotFoundException {
ArrayList<String> inputContents = new ArrayList<>();
Scanner inFile =
new Scanner(new FileReader("H:\\csc8001\\data.txt"));
while(inFile.hasNextLine())
{
String line = inFile.nextLine();
inputContents.add(inFile.nextLine());
}
inFile.close();
ArrayList<String> dictionary = new ArrayList<>();
for(int i= 0; i <inputContents.size(); i++)
{
String newLine = inFile.nextLine();
newLine = newLine(i).replaceAll("[^A-Za-z0-9]");
dictionary.add(inFile.nextLine());
}
// PrintWriter outFile =
// new PrintWriter("H:\\csc8001\\results.txt");
}
There is a compilation error on this line:
newLine = newLine(i).replaceAll("[^A-Za-z0-9]");
Because replaceAll takes 2 parameters: a regex and a replacement.
(And because newLine(i) is non-sense.)
This should be closer to what you need:
newLine = newLine.replaceAll("[^A-Za-z0-9]+", " ");
That is, replace non-empty sequences of non-[A-Za-z0-9] characters with a space.
To convert all uppercase letters to lowercase, it's simpler and better to use toLowerCase.
There are many other issues in your code too. For example, some lines in the input will be skipped, due to some inappropriate inFile.nextLine calls. Also, the input file is closed after the first loop, but the second tries to use it, which makes no sense.
With these and a few other issues cleaned up, this should be closer to what you want:
Scanner inFile = new Scanner(new FileReader("H:\\csc8001\\data.txt"));
List<String> inputContents = new ArrayList<>();
while (inFile.hasNextLine()) {
inputContents.add(inFile.nextLine());
}
inFile.close();
List<String> dictionary = new ArrayList<>();
for (String line : inputContents) {
dictionary.add(line.replaceAll("[^A-Za-z0-9]+", " ").toLowerCase());
}
If you want to add words to the dictionary instead of lines, you also need to split the lines on spaces. One simple way to achieve that:
dictionary.addAll(Arrays.asList(line.replaceAll("[^A-Za-z0-9]+", " ").toLowerCase().split(" ")));

Why is my word counter sometimes off by one?

Most of the time it works correctly. Rarely it counts off by one. Any guess?
public static int countWords(File file) throws FileNotFoundException, IOException{
BufferedReader br = new BufferedReader(new FileReader(file));
String line;
List<String> strList = new ArrayList<>();
while ((line=br.readLine())!=null){
String[] strArray= line.split("\\s+");
for (int i=0; i<strArray.length;i++){
strList.add(strArray[i]);
}
}
return strList.size();
}
Particularly in the example below it gives 3 instead of 2:
\n
k
I guess the second line is split into two string, "" and "k". See the code below:
import java.util.Arrays;
public static void main(String[] args) {
String str = " k";
String[] array = str.split("\\\s+");
System.out.println("length of array is " + array.length); // length is 2
System.out.println(Arrays.toString(array)); //array is [, k]
}
If you are using Java 8, you can use Streams and filter what you consider as a "word". For example:
List<String> l = Files.lines(Paths.get("files/input.txt")) // Read all lines of your input text
.flatMap(s->Stream.of(s.split("\\s+"))) // Split each line by white spaces
.filter(s->s.matches("\\w")) // Keep only the "words" (you can change here as you want)
.collect(Collectors.toList()); // Put the stream in a List
In this specific case, it will output [k].
You can of course do the same in Java 7 by adapting your code and add this condition in your for loop:
if(strArray[i].matches("\\w"))
strList.add(strArray[i]); // Keep only the "words" - again, use your own criteria
It is just more cumbersome.
I hope it helps.

Java: Read a text file into an array

I've a txt file composed by two columns like this:
Name1 _ Opt1
Name2 _ Opt2
Name3 _ Opt3
In each row there's a name, a tab delimiter, a _ and then another name; there are really many rows (about 150000) and i'm not even sure which one is the best constructor to use, i'm thinking about a two dimensional array but it could be also something else if it's a better choice. For me it's important that i can access to the elements with something like this a[x][y].
I've done this but i just know how to count the number of the lines or how to put each lines in a different position of an array.
Here's the code:
int countLine = 0;
BufferedReader reader = new BufferedReader(new FileReader(filename));
while (true) {
String line = reader.readLine();
if (line == null) {
reader.close();
break;
} else {
countLine++;
}
}
Since you don't know the number of lines ahead of time, I would use an ArrayList instead of an array. The splitting of lines into String values can easily be done with a regular expression.
Pattern pattern = Pattern.compile("(.*)\t_\t(.*)");
List<String[]> list = new ArrayList<>();
int countLine = 0;
BufferedReader reader = new BufferedReader(new FileReader(filename));
while (true) {
String line = reader.readLine();
if (line == null) {
reader.close();
break;
} else {
Matcher matcher = pattern.matcher(line);
if (matcher.matches()) {
list.add(new String[] { matcher.group(1), matcher.group(2) });
}
countLine++;
}
The first thing you should do is to write a class that represents an entry in your file. It could be quite sophisticated but a really simple design will probably also do.
class Record {
final String name;
final String option;
Record(final String name, final String option) {
this.name = name;
this.option = option;
}
}
Using this class is much better than messing with arrays of strings.
The second thing to do is to use a more abstract data structure than an array structure to put your records into. This will free you from the burden of having to know the number of elements in advance. I recommend that you use an ArrayList for this. Then, you can read in one record at a time and add it to your collection.
List<Record> records = new ArrayList<Record>();
records.add(new Record("NameX", "OptionX"));
System.out.printf("There are %d records in the list.%n", records.size());
Of course, the second line in the above example should be done over and over again in your loop that reads the lines of the file.
Use ArrayList instead of array because the size is unknown. Use Scanner to read file, and to check existence of next line in file use hasNextLine() method,
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Scanner;
class Test {
static Scanner userInput = new Scanner(System.in);
public static void main(String args[]) throws FileNotFoundException {
int countline = 0;
Scanner inp=new Scanner(new File("/home/nasir/Desktop/abc.txt"));
ArrayList<String> list=new ArrayList<String>();
while(inp.hasNextLine()){
list.add(inp.nextLine());// adding a row in ArrayList
countline++;// counting every line/row
}
System.out.println(countline+" "+list.get(2));
}// Main
}// Class
You can save the data on
HashMap>
The first String (key) is your name
The second String (key) is your opt and his value (reault) is the object result.
You can use it as:
result = youHashMap.get(name).get(opt);

useDelimiter, read up till first delimiter and then change line

I'm trying to use a Delimiter to pull out the first numbers in a document with 31 rows looking something like "105878-798##176000##JDOE" and put it in an int array.
The numbers I'm interesed in are "105878798", and the number of numbers is not consistent.
I wrote this but can't figure out how to change the line when i reach the first delimiter (of the line).
import java.util.*;
import java.io.*;
public class Test {
public static void main(String[] args) throws Exception {
int n = 0;
String rad;
File fil = new File("accounts.txt");
int[] accountNr = new int[31];
Scanner sc = new Scanner(fil).useDelimiter("##");
while (sc.hasNextLine()) {
rad = sc.nextLine();
rad.replaceAll("-","");
accountNr[n] = Integer.parseInt(rad);
System.out.println(accountNr[n]);
n++;
System.out.println(rad);
}
}
}
Don't use the scanner for this, use the StringTokenizer and set the delimiter to ##, then just keep calling .nextElement() and you will get the next number no matter how long it is.
StringTokenizer st2 = new StringTokenizer(str, "##");
while (st2.hasMoreElements()) {
log.info(st2.nextElement());
}
(Of course, you can iterate in different ways..)
I would suggest for each line use line.split("[#][#]")[0] (of course haldle your exceptions).
also, rad.replaceAll(...) returns a new String, because String is an imutable object. you should execute parseInt on the returned String and not on rad.
just use the following instead of the equivalent 2 lines in your code:
String newRad = rad.replaceAll("-","");
accountNr[n] = Integer.parseInt(newRad);

Categories