Why does a call to nextLine() right after nextInt() often return an empty string, and how do you fix it?
answer
- nextInt() leaves the trailing \n in the buffer
- nextLine() eats that leftover newline as an empty line
- Fix: extra sc.nextLine() after the token read
- Or: read all lines, Integer.parseInt yourself
- Affects next()/nextDouble()/nextBoolean() too
basics
~20 snextInt() reads the number but leaves the leftover newline (Enter key) in the buffer. The next nextLine() then reads that empty leftover instead of the next line. Fix it by adding an extra nextLine() to consume the leftover newline.
solid answer
~40 sThis is the classic Scanner gotcha. nextInt() (and other token-reading methods) consume only the number token and stop, leaving the newline character produced by pressing Enter still sitting in the input buffer. When you then call nextLine(), it reads from the current position to the next newline, finds that leftover newline immediately, and returns an empty string. The fix is to consume that dangling newline before reading the line you actually want: call an extra sc.nextLine() after nextInt(), or read everything with nextLine() and parse the numbers yourself with Integer.parseInt. The same issue applies after next(), nextDouble(), and similar token methods. The root cause is that token methods skip leading whitespace but do not consume the trailing line terminator, while nextLine() is line-oriented and treats that terminator as the end of an (empty) line.
code
java · 5 linesScanner sc = new Scanner(System.in);
int age = sc.nextInt(); // reads 30, leaves the newline
sc.nextLine(); // consume leftover newline
String name = sc.nextLine(); // now correctly reads the next line
System.out.println(name + " / " + age);go deeper
Recognizes the empty-string symptom and knows the workaround: add an extra sc.nextLine() after nextInt().
Explains the buffer mechanism (token methods leave the newline, nextLine consumes it) and can prevent it by reading lines and parsing manually.
Generalizes the rule to all token methods, reasons about where the scanner position sits, and chooses a consistent input strategy to avoid mixing token and line reads.
Sets a team convention or wrapper for console parsing that eliminates the class of bug, and weighs Scanner versus BufferedReader for robustness and clarity in shared code.
## The symptom You write code like this and the program seems to skip your input: ```java Scanner sc = new Scanner(System.in); int age = sc.nextInt(); // user types 30, presses Enter String name = sc.nextLine(); // user expects to type a name... System.out.println("[" + name + "]"); // prints [] — empty! ``` The `name` comes back empty even though the user is ready to type. Why? ## The input buffer model When you type `30` and press **Enter**, the characters that arrive in the input buffer are: `3`, `0`, and a **newline** character (`\n`, the thing Enter produces). The buffer therefore contains: ``` 3 0 \n ``` ### What nextInt() does `nextInt()` is a **token method**. It: 1. skips any leading whitespace, 2. reads the next token that looks like an integer (`30`), 3. **stops right there** — it does *not* consume the trailing `\n`. So after `nextInt()` returns `30`, the buffer still contains the leftover newline: ``` \n ``` ### What nextLine() does `nextLine()` is a **line method**. It reads everything from the current position **up to the next newline**, returns that text (without the newline), and consumes the newline. The current position is sitting *right before* that leftover `\n`. So `nextLine()` finds the newline immediately, decides the line is empty, returns `""`, and consumes it. Your real input was never reached. ## The fixes ### Fix 1 — consume the leftover newline Add one extra `nextLine()` after the token read to throw away the dangling terminator: ```java int age = sc.nextInt(); sc.nextLine(); // consume the leftover newline String name = sc.nextLine(); // now reads the real line ``` ### Fix 2 — read lines only, parse yourself Avoid mixing token and line methods. Read whole lines and convert: ```java int age = Integer.parseInt(sc.nextLine().trim()); String name = sc.nextLine(); ``` This keeps everything line-oriented, so there is never a leftover newline problem. `Integer.parseInt` turns the text into an int; `.trim()` removes stray spaces. ## Why this generalizes The leftover-newline trap is **not specific to nextInt()**. It happens after **any token method** — `next()`, `nextDouble()`, `nextBoolean()`, `nextLong()` — because they all leave the line terminator behind. Whenever a token read is followed by `nextLine()`, watch for it. ## Mental rule - **Token methods** (`next`, `nextInt`, ...) leave the newline. - **`nextLine()`** is hungry for the rest of the current line and will eat that leftover newline as an empty line. Mix them carefully, or do not mix them at all.
- Does this problem only occur with nextInt()?No. Every token method (next, nextDouble, nextLong, nextBoolean, etc.) leaves the trailing newline behind, so a following nextLine() can return empty. The fix is the same.
- Why is reading everything with nextLine() and parsing manually sometimes cleaner?Because it keeps all reads line-oriented, eliminating the mismatch between token methods (which leave the newline) and line methods (which consume it), so there is no leftover-newline trap at all.
Token methods take their item off a conveyor belt but leave the empty wrapper (the newline) behind; nextLine() then grabs the wrapper, sees nothing inside, and hands you an empty string.
saying these in an interview costs you the question
- Claiming nextLine() returns empty because the user did not type anything
- Thinking nextInt() consumes the trailing newline
- Believing the bug is a JVM/Scanner defect rather than expected token-vs-line semantics
- Fixing it by calling nextLine() twice blindly without understanding which call eats the leftover