JB Header

Reading User Input in Java with Scanner

Introduction So far our programs have only produced output. To make them interactive, we need to read what the user types. The standard way to do this in a console program is the Scanner class. This tutorial explains reading user input in Java with Scanner, with examples. We will start by creating a Scanner and reading text and numbers. We will then understand how Scanner splits input into tokens, and fix the most common Scanner bug - nextLine() after nextInt(). Next we will validate input so that the program does not crash on bad data, and read an unknown amount of input in a loop. Lastly, we will look at best practices for using Scanner.

(Note - The examples print prompts with print and printfClick to read tutorial: Java Console Output: println, printf and String.format. In the outputs below, the text after each prompt is what the user typed.) Creating a Scanner and reading input Scanner is in the java.util package. To read from the keyboard, create one on System.in, the program's standard input. Its most used methods are -
  • nextLine() - reads the rest of the current line, as a String.
  • next() - reads the next word (token), up to a space or line break.
  • nextInt(), nextLong(), nextDouble(), nextBoolean() - read the next token and convert it to that type.
  • hasNextInt(), hasNextLine() and similar - check what the next input is, without reading it.
Reading a name and an age with Scanner
//Greeting.java
import java.util.Scanner;

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

    System.out.print("Enter your full name: ");
    String name = scanner.nextLine();

    System.out.print("Enter your age: ");
    int age = scanner.nextInt();

    System.out.print("Enter your height in metres: ");
    double height = scanner.nextDouble();

    System.out.printf("Hello, %s! In 10 years you will be %d. Height: %.2f m%n", name, age + 10, height);
  }
}
 OUTPUT of the above code
Enter your full name: Tom Jones
Enter your age: 25
Enter your height in metres: 1.78
Hello, Tom Jones! In 10 years you will be 35. Height: 1.78 m
Explanation of the code
  • import java.util.Scanner; is needed, because Scanner is not in java.lang.
  • nextLine() read the whole line Tom Jones, including the space. next() would have read only Tom.
  • nextInt() and nextDouble() converted the typed text to numbers, so age + 10 is arithmetic, not string joining.
  • Each method blocks - the program waits until the user has typed something and pressed Enter.
How Scanner reads tokens Scanner treats the input as a stream of characters. Methods such as next() and nextInt() skip any whitespace, then read one token - the characters up to the next space, tab or line break. So several values can be typed on one line, separated by spaces -
Reading several numbers from one line
//SumThree.java
import java.util.Scanner;

public class SumThree {
  public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    System.out.print("Enter three numbers: ");
    int a = scanner.nextInt();
    int b = scanner.nextInt();
    int c = scanner.nextInt();
    System.out.println("Sum = " + (a + b + c));
  }
}
 OUTPUT of the above code
Enter three numbers: 10 20 30
Sum = 60
The nextLine() after nextInt() problem This is the most common Scanner bug. nextInt() reads the number, but leaves the line break after it unread. A nextLine() called next finds that line break straight away, and returns an empty string - without waiting for the user.
The nextLine() after nextInt() bug
//NextLineBug.java
import java.util.Scanner;

public class NextLineBug {
  public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    System.out.print("Enter your age: ");
    int age = scanner.nextInt();
    System.out.print("Enter your city: ");
    String city = scanner.nextLine();      // returns the rest of the age line - empty
    System.out.println("Age: " + age + ", city: [" + city + "]");
  }
}
 OUTPUT of the above code
Enter your age: 25
Enter your city: Age: 25, city: []
The program printed the city prompt and finished without reading London - the city is empty. There are two fixes. Either call an extra nextLine() to consume the rest of the number's line, or - more robust - read every line with nextLine() and convert it yourself.
Two ways to fix the nextLine() problem
//NextLineFixed.java
import java.util.Scanner;

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

    // Fix 1: consume the leftover line break
    System.out.print("Enter your age: ");
    int age = scanner.nextInt();
    scanner.nextLine();
    System.out.print("Enter your city: ");
    String city = scanner.nextLine();
    System.out.println("Age: " + age + ", city: [" + city + "]");

    // Fix 2: read whole lines, and parse numbers yourself
    System.out.print("Enter your quantity: ");
    int quantity = Integer.parseInt(scanner.nextLine().trim());
    System.out.print("Enter your product: ");
    String product = scanner.nextLine();
    System.out.println(quantity + " x " + product);
  }
}
 OUTPUT of the above code
Enter your age: 25
Enter your city: London
Age: 25, city: [London]
Enter your quantity: 3
Enter your product: Java book
3 x Java book
Validating input If the user types abc when nextInt() expects a number, it throws an InputMismatchException and the program crashes. Use hasNextInt() to check first, and ask again until the input is valid -
Asking again until the input is a valid number
//ValidatedInput.java
import java.util.Scanner;

public class ValidatedInput {
  public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    int age = -1;
    while (age < 0 || age > 130) {
      System.out.print("Enter your age (0-130): ");
      if (scanner.hasNextInt()) {
        age = scanner.nextInt();
        if (age < 0 || age > 130) {
          System.out.println("  " + age + " is out of range.");
        }
      } else {
        System.out.println("  '" + scanner.next() + "' is not a number.");
      }
      scanner.nextLine();   // discard the rest of the line
    }
    System.out.println("Age accepted: " + age);
  }
}
 OUTPUT of the above code
Enter your age (0-130): abc
  'abc' is not a number.
Enter your age (0-130): 150
  150 is out of range.
Enter your age (0-130): 42
Age accepted: 42
Explanation of the code Reading until the input ends hasNextLine() and hasNextInt() return false when there is no more input. This lets a program read any number of lines - from the keyboard until the user presses Ctrl+D (macOS, Linux) or Ctrl+Z then Enter (Windows), or from a file redirected to the program, as in java Average < numbers.txt.
Reading numbers until the input ends
//Average.java
import java.util.Scanner;

public class Average {
  public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    int count = 0;
    double sum = 0;
    while (scanner.hasNextDouble()) {
      sum += scanner.nextDouble();
      count++;
    }
    System.out.printf("Read %d numbers, average = %.2f%n", count, count == 0 ? 0 : sum / count);
  }
}
 OUTPUT of the above code
12.5 7
3
9.5
Read 4 numbers, average = 8.00
The first three lines are the input - four numbers, two of them on one line - and the last line is the program's output once the input ended. Best practices
  • Create one Scanner for System.in, and pass it to the methods which need it. Several Scanners on System.in can each buffer part of the input, so some input gets lost.
  • Do not close a Scanner on System.in until the program has finished reading. Closing the Scanner also closes System.in, and it cannot be reopened. (A Scanner reading a file should be closed - ideally with try-with-resources.)
  • Validate input with the hasNextXxx() methods, or by reading lines and parsing them, instead of letting bad input crash the program.
  • Know its limits: Scanner is convenient but slow for very large inputs. For those, BufferedReader is the usual choice.
Summary In this tutorial we first created a Scanner on System.in, and read text with nextLine() and numbers with nextInt() and nextDouble(). We then saw how Scanner reads tokens, which lets several values be typed on one line. Next we understood and fixed the nextLine() after nextInt() problem. We then validated input with hasNextInt(), and read numbers until the input ended. Lastly, we went through best practices for using Scanner. This completes the language basics. Next, we start on control flow with if, else if and else statementsClick to read tutorial: Java if, else if and else Statements with Examples.