Skip to content
elephantoo

Reading input with Scanner

Lesson 4 of 43 12 min read

Read numbers, words and whole lines from the keyboard, and avoid the nextInt/nextLine trap.


Until now our programs always did the same thing. Reading input makes them interactive: a calculator that uses your numbers, a quiz that checks your answers. The standard tool for reading keyboard input in beginner programs is java.util.Scanner.

Your first interactive program#

HelloName.java
import java.util.Scanner;

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

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

        System.out.println("Nice to meet you, " + name + "!");
    }
}

A sample run (what you type is shown after the prompt):

Output
What is your name? Ada Lovelace
Nice to meet you, Ada Lovelace!

Step by step:

  1. import java.util.Scanner; makes the class available. Only java.lang (home of String, Math, System) is imported automatically.
  2. new Scanner(System.in) creates a scanner that reads from standard input, which is normally the keyboard.
  3. System.out.print (no ln) prints the prompt without a newline, so the cursor waits on the same line.
  4. in.nextLine() waits until the user presses Enter and returns everything they typed on that line.

Reading different types#

Scanner splits input into tokens separated by whitespace (spaces, tabs, newlines) and can convert each token for you:

MethodReadsExample input
nextLine()the rest of the current line, as a StringNew Delhi
next()the next single word (token)Delhi
nextInt()the next token as an int42
nextLong()a long9000000000
nextDouble()a double3.75
nextBoolean()true or falsetrue
Rectangle.java
import java.util.Scanner;

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

        System.out.print("Width: ");
        double width = in.nextDouble();
        System.out.print("Height: ");
        double height = in.nextDouble();

        double area = width * height;
        System.out.printf("Area = %.2f%n", area);
    }
}
Output
Width: 4.5
Height: 2
Area = 9.00

printf prints formatted text: %.2f means "a decimal number with 2 digits after the point", and %n is a newline. You will learn more format codes in the strings lesson.

Because tokens are separated by any whitespace, the user could also type 4.5 2 on one line and the program would behave the same.

Note: nextDouble() uses your computer's locale. On systems set to, say, German, it expects 4,5 instead of 4.5. To always accept a dot, create the scanner with new Scanner(System.in).useLocale(java.util.Locale.US).

The nextInt() + nextLine() trap#

This is the most common Scanner bug. Try it:

Trap.java
import java.util.Scanner;

public class Trap {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        System.out.print("Age: ");
        int age = in.nextInt();
        System.out.print("City: ");
        String city = in.nextLine();          // BUG: returns "" immediately
        System.out.println(age + " from [" + city + "]");
    }
}
Output
Age: 30
City: 30 from []

When you type 30 and press Enter, the input buffer contains 30\n. nextInt() consumes 30 but leaves the \n. nextLine() then reads "everything up to the next newline", which is nothing, and returns "" without waiting.

Two reliable fixes:

Java
// Fix 1: throw away the rest of the line after reading a number
int age = in.nextInt();
in.nextLine();                 // consume the leftover newline
String city = in.nextLine();

// Fix 2 (recommended): read whole lines and convert them yourself
int age2 = Integer.parseInt(in.nextLine().trim());
String city2 = in.nextLine();

Fix 2 is predictable because every read consumes exactly one line.

Validating input#

Users make typos. If they type ten where you call nextInt(), your program crashes with an InputMismatchException. Use the hasNextXxx() methods to check before reading:

SafeAge.java
import java.util.Scanner;

public class SafeAge {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        System.out.print("Enter your age: ");
        while (!in.hasNextInt()) {
            String bad = in.next();            // discard the invalid token
            System.out.print("'" + bad + "' is not a number. Try again: ");
        }
        int age = in.nextInt();
        System.out.println("In ten years you will be " + (age + 10));
    }
}

With the input ten then 25:

Output
Enter your age: ten
'ten' is not a number. Try again: 25
In ten years you will be 35

The loop keeps discarding bad tokens until a valid integer arrives. You will meet while loops properly in two lessons; the idea here is simply "repeat until valid". Another approach, reading a line and calling Integer.parseInt inside try/catch, is covered in the exceptions lesson.

Reading until the input ends#

hasNextLine() and hasNextInt() return false when input runs out. That lets a program process any amount of data, typed or piped from a file:

SumAll.java
import java.util.Scanner;

public class SumAll {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int sum = 0, count = 0;
        while (in.hasNextInt()) {
            sum += in.nextInt();
            count++;
        }
        System.out.println("Read " + count + " numbers, sum = " + sum);
    }
}
Terminal
echo "4 8 15 16 23 42" | java SumAll.java
Output
Read 6 numbers, sum = 108

When typing at the keyboard, signal "end of input" with Ctrl+D on Linux/macOS or Ctrl+Z then Enter on Windows.

A tiny tip calculator#

Putting it all together, using the line-based approach:

TipCalculator.java
import java.util.Scanner;

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

        System.out.print("Bill amount: ");
        double bill = Double.parseDouble(in.nextLine().trim());

        System.out.print("Tip percent: ");
        int percent = Integer.parseInt(in.nextLine().trim());

        System.out.print("Number of people: ");
        int people = Integer.parseInt(in.nextLine().trim());

        double tip = bill * percent / 100.0;
        double each = (bill + tip) / people;

        System.out.printf("Tip: %.2f%n", tip);
        System.out.printf("Each person pays: %.2f%n", each);
    }
}
Output
Bill amount: 1250
Tip percent: 10
Number of people: 4
Tip: 125.00
Each person pays: 343.75

Closing the Scanner#

A Scanner holds a resource, so tools may warn "resource leak: in is never closed". For a scanner on System.in:

  • Create one scanner for the whole program and reuse it. Creating several scanners on System.in can lose buffered input.
  • Closing it also closes System.in, after which no part of your program can read the keyboard again. In small programs it is fine to let it close when the program ends.

For scanners on files, always close them, ideally with try-with-resources, which you will learn in a later lesson.

Common mistakes#

  • Forgetting import java.util.Scanner; (error: cannot find symbol: class Scanner).
  • Mixing nextInt() with nextLine() without consuming the leftover newline.
  • Creating a new Scanner(System.in) inside a loop or in several methods.
  • Using next() when you wanted a full line: next() stops at the first space, so New Delhi becomes just New.

What's next#

Your programs can now react to the user. Next we teach them to make decisions with if, else and switch.

Check your understanding

Quick quiz

0/3 answered
  1. 1.You call nextInt() and then nextLine(). The user typed 42 and pressed Enter. What does nextLine() return?

  2. 2.What happens if the user types abc when your program calls scanner.nextInt()?

  3. 3.Which import do you need to use Scanner?

Finished reading?

Mark this lesson complete to track your progress.