Reading from the Keyboard


Scanners

Java handles reading using objects that perform the reading for you. There are several different types of objects that read, depending on the details of how you want them to work, but we will only look at objects of type Scanner.

The Scanner class is part of the java.util library package. To use Scanner, add line

  import java.util.*;
just before your class.

To build a scanner that reads from the keyboard, use statement

  Scanner in = new Scanner(System.in);

Now you can use this object, called in, to do the following operations.

Operation Description
in.hasNextDouble( ) Result type: boolean.

Yields true if you can read a value of type double now. (If the user has not yet typed anything then it waits until some information is available before deciding whether the information looks like a real number.)
in.hasNextInt( ) Result type: boolean.

Yields true if you can read a value of type int now.
in.hasNextLong( ) Result type: boolean.

Yields true if you can read a value of type long now.
in.hasNextLine( ) Result type: boolean.

Yields true if there is another line that you an read now.
in.nextDouble( ) Result type: double.

Reads and returns the next value of type double. (It skips over white space, gets the number, and stops at a character that is not a digit, decimal point or other character that can be part of a real number.)
in.nextInt( ) Result type: int.

Reads and returns the next value of type int. (It skips over white space, gets the number, and stops at a character that is not a digit or sign character.)
in.nextLong( ) Result type: long.

Reads and returns the next value of type long. (It skips over white space, gets the number, and stops at a character that is not a digit or sign character.)
in.nextLine( ) Result type: String.

Reads and returns the next line. The string that is returned does not contain the end-of-line marker. (It reads up to an end-of-line marker, and returns the string up to but not including the end-of-line marker. But it does remove the end-of-line marker from the input.)

Each time you read something it is thrown away, so that successive reads get successive values. For example, suppose that the user types

 25 400
Then performing
  int m = in.nextInt();
  int n = in.nextInt();
makes m = 25 and n = 400.

Be careful about nextLine. It reads the rest of the current line. If you are in the middle of a line, or even if you are just before the end, it only gets the rest of this line. For example, suppose that you expect the user to type an integer and a string. You might try to read them as follows.

  Scanner in = new Scanner(System.in);

  System.out.print("How many? ");
  int num = in.nextInt();

  System.out.print("What is your name? ");
  String name = in.nextLine();
But that does not work. The problem is that the user typed a newline character after the integer. Expression in.nextInt( ) reads the integer, but no more. It leaves the end-of-line marker still in the input. Now in.nextLine( ) just reads the rest of the line that contains the integer, which is probably an empty string. A better way to get a number and a string is as follows.
  Scanner in = new Scanner(System.in);

  System.out.print("How many? ");
  int num = in.nextInt();
  in.nextLine();  // Skip the rest of this line.

  System.out.print("What is your name? ");
  String name = in.nextLine();


Scanning a string

We have seen how to read from the keyboard. You can also read from a string as if the string is coming from the keyboard. If s has type String then

  Scanner ins = new Scanner(s);
creates a new scanner called ins that reads from string s. Treat it exactly as you would any other scanner object. For example,
  Scanner ins = new Scanner("20 350\n");
  int x = in.nextInt();
  int y = in.nextInt();
makes x = 20 and y = 350.

Sometimes you read a line of text from the keyboard and then do a separate scan on that line of text. For example, another way to read an integer followed by a name is as follows.

  Scanner in = new Scanner(System.in);

  System.out.print("How many? ");
  String line = in.nextLine()
  Scanner linescan = new Scanner(line);
  int num = linescan.nextInt();

  System.out.print("What is your name? ");
  String name = in.nextLine();
Since this approach always reads full lines, you do not need to worry about the possibility of getting confused because you have read only part of a line.


Avoid creating too many Scanners

It is best to create just one Scanner for any given source of information and to keep using that scanner to do the reading. Do not create a new Scanner object each time you want to read some information. If you do, you can find that some information gets lost, and exactly what is lost is unpredictable.

For example, suppose that you decide to write a method to read an integer from the keyboard, and you write it as follows.

  public static int readInt()
  {
    Scanner in = new Scanner(System.in);
    return in.nextInt();
  }
That does not work because each time readInt is used it creates a new scanner to read from the keyboard. The right way to do that kind of thing is to make one scanner and to pass it to readInt.
  public static int readInt(Scanner in)
  {
    return in.nextInt();
  }


Exceptions

A program can throw an exception when it tries to read something that cannot be read. For example, trying to read an integer when there is no integer present in the input throws exception NoSuchElementException.

Normally, you would be required to have a throws line after the method heading if a method might throw those exceptions. But exception NoSuchElementException is special. It is called a Runtime Exception, and those kinds of exceptions do not need to be written in throws lines. That is why method readInt above does not need a throws line.


A complete program that reads information

To illustrate using scanners, here is a simple program that reads two numbers and writes their greatest common factor.

  import java.util.*;

  public class Gcf
  {
    public static void main(String[] args)
    {
      Scanner in = new Scanner(System.in);
      System.out.print("Gcf of which two numbers? ");
      try
      {
        int a = in.nextInt();
        int b = in.nextInt();
        System.out.println("gcf(" + a + "," + b + ") = " + gcf(a,b));
      }
      catch(NoSuchElementException e)
      {
        System.out.println("I need two integers.");
      }
    }

    public static int gcf(int x, int y)
    {
      if(x == 0) return y;
      else return gcf(y % x, x);
    }
  }

More information

Input from the keyboard is discussed in Chapter 2.3 of Savitch and Carrano.


Summary

You read using an object that does the reading for you. We have looked at objects of class Scanner.