🔀 Control Flow · Beginner

Reading user input in Java

Scanner basics, nextInt vs nextLine pitfall.

🧩 The mysteryYour program asks "Age?" then "Name?". You type 30, press Enter... and the program ends without ever letting you type a name. Ghosts? No: a leftover keystroke.

Meet Scanner

Scanner wraps System.in (the keyboard) and splits typed text into tokens: chunks separated by whitespace. nextInt(), nextDouble() and next() each read one token. nextLine() reads the rest of the current line.

Scanner sc = new Scanner(System.in);
int age = sc.nextInt();     // one token
String word = sc.next();    // one word
String rest = sc.nextLine(); // rest of line
🔮 Predict it

Simulated typing

A Scanner can also read from a String, handy for testing. The "user" typed 30, Enter, Ana, Enter. What prints?

Scanner sc = new Scanner("30\nAna\n");
int age = sc.nextInt();
String name = sc.nextLine();
System.out.println("[" + name + "]");
  1. [Ana]
  2. []
  3. [30]
Show the answer

[], an empty string! nextInt() read the digits 30 and stopped *before* the Enter. Then nextLine() read from there to that Enter: nothing.

The leftover Enter

The input is really 30⏎Ana⏎. **nextInt() takes only the digits and leaves the newline in the buffer.** The next nextLine() happily reads "everything up to the newline", which is empty, and returns "" immediately. The user never gets to type.

// buffer: 3 0 ⏎ A n a ⏎
sc.nextInt();  // takes 3 0
sc.nextLine(); // takes up to ⏎ → ""

Reading a number, then a line

✗ Skips the name
int age = sc.nextInt();
String name = sc.nextLine();

name is the empty rest of the number's line.

✓ Eats the newline
int age = sc.nextInt();
sc.nextLine(); // discard rest
String name = sc.nextLine();

One extra nextLine() clears the leftover. Or read every line and parse it: Integer.parseInt(sc.nextLine()). Don't create a second Scanner on System.in: the first may already have buffered the input.

🔮 Predict it

With the fix

Same input, one extra line. What prints?

Scanner sc = new Scanner("30\nAna\n");
int age = sc.nextInt();
sc.nextLine();
String name = sc.nextLine();
System.out.println(name + " is " + age);
  1. Ana is 30
  2. is 30
  3. Ana is 0
Show the answer

The extra nextLine() swallows the leftover newline, so the second nextLine() reads the real line: Ana.

⚠️ The trap

Letters where a number should be

If the user types abc and you call nextInt(), Scanner throws **InputMismatchException** and leaves abc unread. Peek first with **hasNextInt()**: it checks whether an int comes next *without reading it*.

if (sc.hasNextInt()) {
    int n = sc.nextInt();
} else {
    sc.next(); // discard the bad token
}

Java 25's shortcut

Java 25 finalized the **IO** class in java.lang. IO.readln("Name: ") prints the prompt and returns the whole line the user types: no Scanner, no leftover newlines. IO.println and IO.print write output.

String name = IO.readln("Name: ");
int age = Integer.parseInt(
    IO.readln("Age: "));
IO.println("Hi " + name);
💼 In the real world

In real projects

The nextInt()/nextLine() trap is a classic in coding-challenge sites and exam questions, where input arrives in exact formats. Real tools validate every input (never trust users!) and often read whole lines and parse them, which avoids the trap entirely.

Key takeaways

  1. Scanner sc = new Scanner(System.in); creates the reader
  2. nextInt() reads a number but leaves the newline in the buffer
  3. Fix: call an extra sc.nextLine() after nextInt(), or read lines and parse them
  4. Java 25 adds IO.readln("Prompt: ") for quick line input
🤯 Did you know?

Scanner arrived in Java 5 (2004). Before that, reading a number from the keyboard meant wrapping System.in in an InputStreamReader, then a BufferedReader, then calling Integer.parseInt.

Practice questions

The user types 30 and presses Enter. The program ends without ever waiting for a name. Why?

Scanner sc = new Scanner(System.in);
System.out.print("Age: ");
int age = sc.nextInt();
System.out.print("Name: ");
String name = sc.nextLine();
  1. nextLine() only works before any nextInt() call
  2. nextInt() left the newline behind, and nextLine() read that empty rest of the line
  3. print() doesn't flush, so the second prompt is skipped
  4. Scanner closes itself after reading a number
Check your answer

nextInt() left the newline behind, and nextLine() read that empty rest of the line. After nextInt() reads 30, the input still holds the newline. nextLine() reads up to that newline and returns an empty string immediately.

What's the best fix for the skipped name in the previous program?

  1. Replace nextLine() with nextInt()
  2. Create a second Scanner for the name
  3. Call sc.nextLine() once right after nextInt() to consume the leftover newline
  4. Add Thread.sleep(1000) before reading the name
Check your answer

Call sc.nextLine() once right after nextInt() to consume the leftover newline. One extra nextLine() discards the rest of the number's line. A second Scanner on System.in is a bad idea: the first one may already have buffered the input.

World 5: Methods! You've written everything inside main. Next, package code into named, reusable machines, and discover why Java can never write a method that swaps two of your variables.