The Scanner Class

 

            Because of the complications of the levels of hierarchy in the Files class, starting in Java 1.5, a new class was introduced, called the Scanner class.  It is in the class java.util.Scanner, so to use it, one must have

 

import java.util.*;

 

inside the class which is using it.  The Scanner class can only be used for text files (i.e., ASCII encoded files) to parse primitive data types (char, int, double, etc.).  In general, it will read from the file byte by byte until it finds a whitespace. A whitespace is one of three characters: (1) blank space, (2) tab, or (3) a line feed.  We refer to the data read in between whitespaces as tokens.  (Note, for example, that three consecutive blank characters are considered to be just one whitespace.)  You type in the line feed by hitting the Enter key on your keyboard.

 

 

               The advantage of using an object of the Scanner class is that one only has to create it, and then one can read in data using the appropriate methods of the class.  For example, if we have the data of the type in a file called Sample.txt:

 

                widget 14 3.35

              

 

then the following code will read in it:

 

               String name;

                int units;

                double price;

 

              File inputFile = new File(“Sample.txt”);

               Scanner input = new Scanner(inputFile);

 

               Note that we can do this in one line with:

 

               Scanner input = new Scanner(new File(“Sample.txt”));

 

               name = input.next();

               units = input.nextInt();

               price = input.nextDouble();

 

 

               The method next, reads in character by character as a char until it finds a whitespace.  Similarly, nextInt reads in character by character (from the previous whitespace) until if finds a whitespace.  (Note that three consecutive characters of whitespace are considered to be just one whitespace.)  So for the above, name will have the value of “widget”, units the value of 14, and price the value of 3.35.

 

               There are also methods in the Scanner class which allow you to see what the next input is without having to actually get it.  E.g., one has a method hasNextInt which returns true if and only if the next token in the scanner’s input can be interpreted as an int.  However, it does not actually get it. 

 

               You can also use the Scanner class to read in from the console window.  Just as System.out is the reference to putting output to the console window, the System.in is the reference to getting input from the console window.  Thus,

 

               Scanner console = new Scanner(System.in);

 

               int a,b;

 

               System.out.print(“Give the first number:  “);

               a = console.nextInt();

               System.out.print(“Give the second number:  “);

               b = console.nextInt();

               System.out.print(“The sum of the two numbers given is “+ (a + b));

 

               Then, when this program executes, at the console window, one would see the following:

 

               Give the first number:

 

If one type in a 6, followed by the Enter key, the console window would look like:

 

               Give the first number: 6

               Give the second number:

 

Next, if one typed in a 51 and again hit the Enter key, the console window would look like:

 

               Give the first number: 6

               Give the second number: 51

               The sum of the two numbers given is 57

 

This is because, when one typed in the first number 6, it was read in by the Scanner class object scan and stored in the variable a.  The next time the object scan read in the number 51 and assigned it to b.

 

               Note that if one had written for the last line the following:

 

               System.out.print(“The sum of the two numbers given is “+ a + b);

 

The output would have been

 

               The sum of the two numbers given is 651

 

Why is this so?

 

 

               Note that if one does the following for the above:

 

               Give the first number: 6

               Give the second number: 3a

 

Then the line of

              

               b = console.nextInt();

 

will not be able to convert the “3a” into an integer.  The program will terminate at this point because an exception has happened.  This type of exception is called a InputMismatchException by Java.  It is called this because the input given in “3a” does not match the input expected, an “integer”.

 

Java incorporates a mechanism, known as exception handling, to manage run-time errors that are detected by the Java Virtual Machine, including those that result from illegal input. The term exception refers to a run-time failure. It said that the program throws an exception when it encounters a run-time error that is too severe to continue normally. For example, a file security violation within a program results in an exception. Similarly, when a program attempts to create a new file on a disk that is already full, an exception is thrown.

 

The preferred way to deal with an exception is a try instruction. A try instruction is a Java statement that has a body, much the same way a method has a body. When the try statement executes, its body executes. If no exceptions are thrown during the execution of the try's body, then the catch clauses are ignored, and execution proceeds as though there were no try instruction.

 

Every Java exception has some type, and if an exception is thrown within a try body and if the exception has a type matching one of the catch clauses, then the remainder of the try body is skipped and the matching catch clause is executed.  

 

If an exception is thrown and caught by the appropriate catch clause, then after the catch clause finishes executing, the next instruction to be executed is the first instruction after that clause.  That is to say, if one has:

 

               try

               {

                              

                               a;

                              

               }

               catch(…)

               {

                              

               c;
}

               b;

 

Suppose during the execution of instruction a there is a run-time exception generated which is caught by the catch phrase.  After the execution of instruction c, then next instruction to be executed is instruction b.  Any instruction after a that is inside the try clause is not executed. Instruction a is not completed. 

 

 

 

 

 One handles the bad input above with the try…catch clause for exceptions.  Thus, one would have the following code:

 

               int a,b;

               boolean goodData;

 

               goodData = false;

               while(!goodData)

               {

                               try

                               {

                                              System.out.print(“Give the first number:  “);

                                              a = console.nextInt();

                                              goodData = true;

                               }

                               catch(InputMismatchException e)

                               {

                                              //handle the exception here

                                              System.out.println(“Bad input data, you must give an integer”);

                               }

               }//end while loop

 

               goodData = false;

               while(!goodData)

               {

                               try

                               {

                                              System.out.print(“Give the second number:  “);

                                              b = console.nextInt();

                                              goodData = true;

                               }

                               catch(InputMismatchException e)

                               {

                                              //handle the exception here

                                              System.out.println(“Bad input data, you must give an integer”);

                               }

               }//end while loop

 

 

              

               System.out.print(“The sum of the two numbers given is “+ (a + b));

 

 

               This would be a robust way to make sure “good” data was input in and the program did not break.  The reason that this works is as follows.  Suppose that the input for the first number is 6, while the second number gives the input of 3a.  Then for the first while clause, since the input is good data, the value of 6 is assigned to the variable a.  Then the next line of goodData = true is executed.  Since the exception is not generated, the catch clause is ignored and one terminates the body of the loop.  As goodData has its value set to true, the while loop is finished.

 

               For the second input, since 3a is input and it can not be converted into an integer, the flow of control jumps over the remaining lines of code (goodData = true;) and jumps to the catch clause.  It outputs the System.out.println statement and finishes the body of the while loop (the next line after the catch clause). Then the while condition has not been satisfied (goodData is still false), so it re-enters the body of the loop and retries to get the second integer.  It will remain inside the while loop until good data is input. 

 

               The console terminal would look like the following:

 

 

 

               Give the first number: 6

               Give the second number: 3a

               Bad input data, you must give an integer

               Give the second number: 51

               The sum of the two numbers given is 57