Reputation: 49
I am looking for a little help. I have done quite a bit of googling with little success.
I am new to programming and am sure this is a silly oversight on my part.
The below code is intended to read through a .txt document that is tab delimited. The .txt file is formatted into six columns. Currently, as I move through the file I parse the string to the appropriate value type and assign it to its respective variable. Code is here:
try {
s = new Scanner(new BufferedReader(new FileReader(file))).useDelimiter("\t");
while (s.hasNextLine()) {
group = Integer.parseInt(s.next());
death = Integer.parseInt(s.next());
name = s.next();
sex = s.next();
age = Integer.parseInt(s.next());
fare = Double.parseDouble(s.next());
System.out.println("Class = " + group); // Test that value is being assigned
System.out.println("Death = " + death); // Test that value is being assigned
System.out.println("Name = " + name); // Test that value is being assigned
System.out.println("Gender = " + sex); // Test that value is being assigned
System.out.println("Age = " + age); // Test that value is being assigned
System.out.println("Fare = " + fare); // Test that value is being assigned
}
} finally {
if (s != null) {
s.close();
}
}
When I reach the last column of the first row, the variable fare is set to row 1 column 6 AND row 2 column 1. For some reason the line break is not triggering the while loop to restart.
Can anyone help me understand why the while loop does not restart at the end of the line?
File looks like this:
1 5 Bryan male 25 211.3375
1 2 Jimmy male 22 151.5500
There is about 1200 lines of this. When running this loop I get the below error when attempting to set fare = 211.3375 at the end of the first row. For some reason, the line break isn't resetting the loop. I can only assume that the line break is not interpreted as a tab but do not know how to correct this.
Exception in thread "main" java.lang.NumberFormatException: For input string: "211.3375
1"
Upvotes: 1
Views: 179
Reputation: 285405
You're checking Scanner#hasNextLine()
but then reading multiple Scanner#next()
, a dangerous thing to do. I suggest if you check for next line, you should read next line, and then parse through that line.
e.g.,
while (s.hasNextLine()) {
String line = s.nextLine();
Scanner lineScanner = new Scanner(line);
group = lineScanner.nextInt();
death = lineScanner.nextInt();
name = lineScanner.next();
sex = lineScanner.next();
age = lineScanner.nextInt();
fare = lineScanner.nextDouble();
lineScanner.close();
System.out.println("Class = " + group); // Test that value is being assigned
System.out.println("Death = " + death); // Test that value is being assigned
System.out.println("Name = " + name); // Test that value is being assigned
System.out.println("Gender = " + sex); // Test that value is being assigned
System.out.println("Age = " + age); // Test that value is being assigned
System.out.println("Fare = " + fare); // Test that value is being assigned
}
But even this is somewhat dangerous because I'm calling Scanner#next...()
without first checking. And so perhaps safer would be to do
String[] tokens = line.split("\\s+");
Then count the tokens length to be sure that it's right, and then parse each individual token that needs parsing to numeric type.
Or you could do something like:
while (s.hasNextLine()) {
String line = s.nextLine();
Scanner lineScanner = new Scanner(line);
if (lineScanner.hasNextInt()) {
group = lineScanner.nextInt();
}
if (lineScanner.hasNextInt()) {
death = lineScanner.nextInt();
}
if (lineScanner.hasNext()) {
name = lineScanner.next();
}
if (lineScanner.hasNext()) {
sex = lineScanner.next();
}
if (lineScanner.hasNextInt()) {
age = lineScanner.nextInt();
}
if (lineScanner.hasNextDouble()) {
fare = lineScanner.nextDouble();
}
lineScanner.close();
System.out.println("Class = " + group); // Test that value is being assigned
System.out.println("Death = " + death); // Test that value is being assigned
System.out.println("Name = " + name); // Test that value is being assigned
System.out.println("Gender = " + sex); // Test that value is being assigned
System.out.println("Age = " + age); // Test that value is being assigned
System.out.println("Fare = " + fare); // Test that value is being assigned
}
or use try/catch blocks to check for bad files.
Upvotes: 4