Console Input

Scanner

System.in is an object that represents input from the console. We will be using another class, however, to do our console input. System.in mainly contains functions for low-level input, but the Scanner class can be used on top of System.in to get more useful input. For more details on Java specifics and the Standard Input buffer, you can look at the Java Primer.

Using Scanner

In order to use the Scanner class, a program must include the following line at the start of the file:

import java.util.Scanner;

This statement tells Java to include the Scanner class from the library java.util.

The first step needed to use the Scanner class is to create an instance of it:

import java.util.Scanner;

// ...

    public static void main(String args[])
    {
        Scanner input = new Scanner(System.in);
    }

// ...

The argument passed to create a Scanner object is the stream to which it should be attached. Scanner can be used to read from any stream, including files, but for now we are reading from the console, so we use System.in, which is the default console input for Java.

Scanner Methods

After the object is created, the methods of Scanner can be used to read information from the console. There are several methods used for reading in different types of objects:

import java.util.Scanner;

// ...

    public static void main(String args[])
    {
        Scanner input = new Scanner(System.in);

        //Read in token as double
        double d1 = input.nextDouble();
        //Read in token as int
        int i1 = input.nextInt();
        //Read in token as string
        String s1 = input.next();

        //Print the tokens out
        System.out.println("i1 is " + i1);
        System.out.println("s1 is " + s1);
        System.out.println("s2 is " + s2);
    }

// ...

Each input is separated by whitespace (any number of spaces, tabs, or newlines).

Given the code:

s1 = input.next();
s2 = input.next();

If the input typed into the console is "hello world", then s1 will contain "hello" and s2 will contain "world". (Note that there will still be a remaining newline character in the input buffer.)

Scanner also contains a method for reading the entire line of input.

String s1 = input.nextLine();

Instead of stopping at any whitespace, nextLine() only stops at a newline character. A newline in Java is signified by the escape sequence '\n'. This character is generated by pressing enter at the console. When nextLine() is called, it reads in the '\n', but doesn't add it to the resulting string. So, your input does not contain it, but it also won't be left over in the input buffer for the next time you try and read from the console.

List of Useful Methods

For each ‘next’ function, there is also an equivalent 'hasNext' function that can be used to check if the input stream actually contains the data type you are looking for. This can be useful for validating input. A complete list of the Scanner methods can be found here.

Things to Watch For

When mixing nextLine() and other input methods, there are a few things to consider. nextLine() discards the ending '\n' character, but the other input methods do not. This can lead to unexpected results. For example:

import java.util.Scanner;

// ...

    public static void main(String args[])
    {
        Scanner input = new Scanner(System.in);
        double i1 = input.nextDouble();
        String s1 = input.nextLine();
        String s2 = input.nextLine();

        System.out.println(i1);
        System.out.println(s1);
        System.out.println(s2);
    }

// ...

If the input is given as follows:

2
hello
world

i1 will contain '2', but s1 will contain only a newline character, '\n', and s2 will contain 'hello\n'. To avoid this, an extra nextLine() can be inserted after nextDouble() to discard the '\n'. Here is a visual representation of what is happening on the input buffer:

So the output will be:

2

hello
A good way of fixing this problem is to put a call to nextLine() immediately after any call to nextInt(), nextDouble() and nextFloat() so that the ā€œ\nā€ can get eaten. You should also put a call to nextLine() after a call to next() when you know that you've read t to the end of the line.