Parsing lines of a file
Text files are usually organized into lines, and so a loop for processing a text file usually has the following form:open the file while there are more lines get the next line process the line close the fileThe step where it says "process the line" can be quite involved, however. For example, suppose a file contains lines such as
Firstname Lastname 8 10 7 7 4where the numbers are lab scores, and the desired output for each line is to print the name followed by the sum of the scores divided by a fixed possible total. If the total possible in this case is 50, we'd get output of the form
Firstname Lastname 7.2for this line. The pseudocode for "process the line" might look like this:
read the first name read the last name while there are more numbers add the numbers to the total print name and averageEach line is just a string that you can read with a temporary
Scanner
.
This is simplest if you first write a helper method whose job is to process just one line
and print the name and average:
private static void printOneAverage(String line, int pointsPossible) { // construct a temporary scanner, just to read data from this line Scanner temp = new Scanner(line); // get the first and last name String first = temp.next(); String last = temp.next(); // add up all the scores double total = 0.0; while (temp.hasNextInt()) { int value = temp.nextInt(); total += value; } // print the average double average = total / pointsPossible; System.out.println(first + " " + last + " " + average); }Then the original pseudocode is captured in a method that opens and reads the file, calling
printOneAverage
for each line:
private static void printAllAverages(String filename, int pointsPossible) throws FileNotFoundException { // open the file File file = new File(filename); Scanner scanner = new Scanner(file); // while there are more lines... while (scanner.hasNextLine()) { // get the next line String line = scanner.nextLine(); // process the line printOneAverage(line, pointsPossible); } // close the file scanner.close(); }Then the code for the main method is simple:
public class QuizAverager { public static void main(String[] args) throws FileNotFoundException { // read from a file called "scores.txt", assume total possible points is 50 printAllAverages("scores.txt", 50); }Try this on the sample text file scores.txt. You can find the complete QuizAverager.java source code here.
Advice: When you read a file, decide whether you want to read it item-by-item, or line-by-line. Use
hasNextLine()
with nextLine()
; use hasNext()
with next()
. Don't mix them up.
Checkpoint 1
- Modify the code for
LineNumberer
so that the input file comes from a different project, using a relative path to identify it. For example, runLineNumberer
on the source fileSimpleLoops.java
that was part of lab 5. - Write a method that reads a text file and, for each line, prints out the number of words in the line. Try it on the file story.txt.