Zeeboot
Zeeboot

Reputation: 49

When parsing text file input does not move to next line

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

Answers (1)

Hovercraft Full Of Eels
Hovercraft Full Of Eels

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

Related Questions