Java Programming: Reading a Line at a Time - dummies

Java Programming: Reading a Line at a Time

By Barry Burd

In this Java code listing, the payOneEmployee method illustrates some useful tricks for reading data. In particular, every scanner that you create has a nextLine method. (You might not use this nextLine method, but the method is available nonetheless.)

When you call a scanner’s nextLine method, the method grabs everything up to the end of the current line of text. In this listing, a call to nextLine can read a whole line from the EmployeeInfo.txt file. (In another program, a scanner’s nextLine call may read everything the user types on the keyboard up to the pressing of the Enter key.)

import java.util.Scanner;
import java.io.File;
import java.io.IOException;
public class DoPayroll {
    public static void main(String args[])
                                  throws IOException {
        Scanner diskScanner =
            new Scanner(new File("EmployeeInfo.txt"));
        for (int empNum = 1; empNum <= 3; empNum++) {
            payOneEmployee(diskScanner);
        }
        diskScanner.close();
    }
    static void payOneEmployee(Scanner aScanner) {
        Employee anEmployee = new Employee();
        anEmployee.setName(aScanner.nextLine());
        anEmployee.setJobTitle(aScanner.nextLine());
        anEmployee.cutCheck(aScanner.nextDouble());
        aScanner.nextLine();
    }
}

Notice the careful choice of words: nextLine reads everything up to the end of the current line. Unfortunately, what it means to read up to the end of the current line isn’t always what you think it means. Intermingling nextInt, nextDouble, and nextLine calls can be messy. You have to watch what you’re doing and check your program’s output carefully.

To understand all this, you need to be painfully aware of a data file’s line breaks. Think of a line break as an extra character, stuck between one line of text and the next. Then imagine that calling nextLine means to read everything up to and including the next line break.

Now take a look at this figure.

Visual example of how Java scans content in its programs.

  • If one call to nextLine reads Barry Burd[LineBreak], the subsequent call to nextLine reads CEO[LineBreak].

  • If one call to nextDouble reads the number 5000.00, the subsequent call to nextLine reads the [LineBreak] that comes immediately after the number 5000.00. (That’s all the nextLine reads — a [LineBreak] and nothing more.)

  • If a call to nextLine reads the [LineBreak] after the number 5000.00, the subsequent call to nextLine reads Harriet Ritter[LineBreak].

So after reading the number 5000.00, you need two calls to nextLine in order to scoop up the name Harriet Ritter. The mistake that you usually make is to forget the first of those two calls.

Look again at the file in the figure. For this section’s code to work correctly, you must have a line break after the last 10000.00. If you don’t, a final call to nextLine makes your program crash and burn. The error message reads NoSuchElementException: No line found.

You might be surprised by the number of quirks that you find in each programming language’s scanning methods. For example, the first nextLine that reads from the file in the figure devours Barry Burd[LineBreak] from the file.

But that nextLine call delivers Barry Burd (without any line break) to the running code. So nextLine looks for a line break, and then nextLine loses the line break. Yes, this is a subtle point. And no, this subtle point hardly ever causes problems for anyone.

If this business about nextDouble and nextLine confuses you, please don’t put the blame on Java. Mixing input calls is delicate work in any computer programming language. And the really nasty thing is that each programming language approaches the problem a little differently.

What you find out about nextLine in Java helps you understand the issues when you get to know C++ or Visual Basic, but it doesn’t tell you all the details. Each language’s details are unique to that language.