Você está na página 1de 5

24-1

Lesson 24..Processing File Input with Scanner


We are going to illustrate the use of the Scanner class with lines of text that we input from a file.
First, we will look at how to process numbers that are embedded in the text that makes up the
various lines of an ASCII text file.
Suppose we consider text files with the following properties:
1. They will have an unknown number of lines of text.
2. Each line of text consists of an unknown number of integers separated by spaces.
Following is an example of the contents of such a file (NumData.in stored in your standard
temp_Name folder):
12 10 3 5
18 1 5 92 6 8
2 9 3 22 4 11 7
Adapting to unpredictability:
When we write our program, we want to remember that this file has elements of
unpredictability. There are an unpredictable number of lines of text. Furthermore, each
line of text contains an unpredictable number of integers.
Here is our task. We are to input the lines of text and then print the sum of the numbers in
each line. For example, the sum of the numbers in the first line is:
12 + 10 + 3 + 5 = 30
Similarly, the other lines of text yield:
18 + 1 + 5 + 92 + 6 + 8 = 130
2 + 9 + 3 + 22 + 4 + 11 + 7 = 58
We are required to process the data in such a way that the final printout appears as
follows:
12 + 10 + 3 + 5 = 30
18 + 1 + 5 + 92 + 6 + 8 = 130
2 + 9 + 3 + 22 + 4 + 11 + 7 = 58
Begin the new class:
Lets begin our new InputNumData class as follows:
import java.io.*; //necessary for File and IOException
import java.util.*; //necessary for Scanner
public class InputNumData
{
public static void main( String args[] ) throws IOException
{
Scanner sf = new Scanner(new File("C:\\temp_Name\\NumData.in"));
int maxIndx = -1; //-1 so when we increment below, the first index is 0

24-2
String text[] = new String[1000]; //To be safe, declare more than we
need
while(sf.hasNext( ))
{
maxIndx++;
text[maxIndx] = sf.nextLine( );
//System.out.println(text[maxIndx]); //Remove rem for testing
}
//maxIndx is now the highest index of text[], -1 if no text lines
sf.close( ); //We opened a file above, so close it when finished.
process the text[] array
}
}
Notice that the while-loop automatically adjusts to an unpredictable number of lines of
text. We exit the loop with the lines of text stored in text[ ] and with maxIndx being the
highest index.
Processing the text:
Our real job here is to fill in code in the area of process the text[ ] array. To do this,
we will set up a loop to process the text[ ] elements. As the first line inside the loop, we
will create another Scanner object where text[j] is the String to be tokenized (parsed).
for(int j =0; j <= maxIndx; j++)
{
Scanner sc = new Scanner(text[j]);
//Notice we create a new object each time through the loop

...
}
Now, we will adjust to the unpredictable number of integers in each line of text by using
a while loop and the Scanner method hasNext( ) as follows:
String answer = ; //We will accumulate the answer string here.
int sum; //accumulates sum of integers
for(int j =0; j <= maxIndx; j++)
{
Scanner sc = new Scanner(text[j]);
sum = 0; //important to set to 0; otherwise it will remember the last sum
answer = ; //otherwise it will remember last answer String
while( sc.hasNext( ) ) //We could also have used hasNextInt( ) here
{
int i = sc.nextInt( );
answer = answer + + + i;
sum = sum + i;
}
answer = answer + = + sum;
System.out.println(answer);

24-3
}
As we learned in Lesson 7, use of the Scanner class necessitates the import of java.util.*.
The resulting printout:
+ 12 + 10 + 3 + 5 = 30
+ 18 + 1 + 5 + 92 + 6 + 8 = 130
+ 2 + 9 + 3 + 22 + 4 + 11 + 7 = 58

Project Get Rid of That Leading Plus Sign!


The above is fairly close to what we want except that we have a leading + to eliminate from
each line. This is left as an exercise for the student.

A more complex task:


For our next application of file input using Scanner, we will consider lines of pure
alphabetical characters. The text file we will use will be called Names.in and will be
stored on a flash drive. The path to the flash drive will be E:\Names.in. (Your
instructor may have you put the file on your hard drive if you do not have a flash drive.)
The contents of this file will be:
Sally Jones
Laura Bush
Charlene Tilton
Marilyn Monroe
Judy Ellison
Felecia Garza
Minerva Perez

Output will be:


Bush, Laura
Ellison, Judy
Garza, Felecia
Jones, Sally
Monroe, Marilyn
Perez, Minerva
Tilton, Charlene

There are two things required of the output that we observe above.
1. The names have been reversed with the last name occurring first followed by a
comma and then the first name.
2. The reversed names are listed in alphabetical order.
Reversing the names:
We will call our class AlphNames; however, for now we will skip immediately to the
code that follows the while-loop that inputs the lines of text from the file into the array,
text[ ]. Our code begins with the assumption that we have the following:
text[0] = Sally Jones
text[1] = Laura Bush
...
The first thing we will do is produce a new unsorted array reversedName[ ] that will
appear as follows:
reversedName[0] = Jones, Sally
reversedName[1] = Bush, Laura

24-4
...
Here is the code that will accomplish all this:
String reversedName[] = new String[maxIndx + 1];
for (int j = 0; j <= maxIndx; j++)
{
Scanner sc = new Scanner( text[j] );
String firstName = sc.next( );
String lastName = sc.next( );
reversedName[j] = lastName + , + firstName;
}
Sorting the new array:
Finally, we need a way to sort the array, reversedName[ ]. Recall from Lesson 19 that its
done like this: (The for-loop prints the sorted array.)
Arrays.sort(reversedName); //requires import java.util.*
for (int j =0; j <= maxIndx; j++)
{
System.out.println( reversedName[j] );
}
Finally, the entire class is as follows:
import java.io.*; //for File and IOException
import java.util.*; //necessary for Arrays.sort( ) and Scanner
public class AlphNames
{
public static void main(String args[]) throws IOException
{
Scanner sf = new Scanner(new File("A:\\Names.in"));
int maxIndx = -1; //-1 so when we increment below, the first index is 0
String text[] = new String[1000]; //to be safe, declare more than we
need
while(sf.hasNext( ))
{
maxIndx++;
text[maxIndx] = sf.nextLine( );
}
//maxIndx is now the highest index of text[], = -1 if no text lines
sf.close( ); //We opened a file above, so close it when finished.
String reversedName[] = new String[maxIndx + 1];
for (int j = 0; j <= maxIndx; j++)
{
Scanner sc = new Scanner( text[j] );
String firstName = sc.next( );
String lastName = sc.next( );

24-5
reversedName[j] = lastName + , + firstName;
}
Arrays.sort(reversedName);
for (int j =0; j <= maxIndx; j++)
{
System.out.println( reversedName[j] );
}
}
}

Project Student Averages


Create the following text file called StudentScores.in and store in your standard folder
(temp_Name).
File contents:
Agnes 56 82 95 100 68 52
Bufford 87 92 97 100 96 85 93 77 98 86
Julie 99 100 100 89 96 100 92 99 68
Alice 40 36 85 16 0 22 72
Bobby 100 98 92 86 88

Program output:
Agnes, average =
Bufford, average
Julie, average =
Alice, average =
Bobby, average =

76
= 91
94
39
93

Each line of the file consists of a students name followed by an unpredictable number of test
scores. The number of students is also unpredictable. The desired output is as shown where the
numbers there represent the average test score rounded to the nearest whole number.
Create a class called StudentAverages that will input the StudentScores.in text file and produce
the indicated output.