Almost every Java learner encounters this problem at some point.
You write a simple program that asks for an age (int) and then a name (String). You run it, type an age, press Enter, and the program appears to skip the name input entirely.
It feels like a glitch.
But in reality, you have encountered what developers call the Scanner buffer issue. To keep things simple for beginners, I like to call it the nextLine() issue.
The Problem
Code That “Should” Work
Take a look at this snippet:
Scanner sc = new Scanner(System.in);
System.out.println("Enter an age");
int age = sc.nextInt();
// Example input: 25
System.out.println("Enter a name");
String name = sc.nextLine();
// Example input: Ahi
System.out.println("Name: " + name);
System.out.println("Age: " + age);
You might expect the following interaction:
Enter an age
25
Enter a name
Ahi
Sadly, it is not that simple.
When you type 25 and press Enter, the program finishes before you can even type the name. Therefore, the actual output is:
Name:
Age: 25
Why did this happen? Let’s investigate.
Important note:
I’ve included a quick glossary at the bottom to help you with unfamiliar terms.
Investigation
What Happens Inside?
When you use the Scanner class to read input from the keyboard, every key you press is first stored inside the input buffer as a character.
The characters remain in the buffer until:
- The program consumes them (that is, takes them out of the buffer) using methods like
next(),nextInt(),nextLine(), or - The program terminates.
The Scanner class reads input using two strategies:
- Token-based parsing
- Line-based parsing
Every character inside the buffer is examined one by one.
Depending on the parsing rules being applied, a character will either be:
- Consumed and returned (removed from the buffer and included in the result)
- Consumed and discarded (removed from the buffer but not returned as part of the result)
- Left in the buffer (to be processed later)
Token-Based Parsing
In this approach, input is divided into tokens and one token is returned at a time.
Rules
- Leading delimiters are consumed and discarded.
- From the first non-delimiter character, characters are consumed until a delimiter is detected.
- The detected delimiter is left in the buffer.
- The consumed characters are returned to the program as one token.
Methods That Use This Approach
next()nextInt()nextDouble()nextFloat()nextLong()nextBoolean()
Line-Based Parsing
In this approach, input is read as an entire line.
Rules
- Characters are consumed continuously, including whitespace characters (spaces and tabs).
- Reading continues until a line terminator (
'\n') is encountered. - The line terminator is consumed and discarded.
- All characters before the line terminator are returned as a single
String.
Method That Uses This Approach
nextLine()
Observation: Understanding the Behaviour
Now that we understand how input is read, let us trace the execution of our “failing” code to identify where things went wrong.
Step 1: Input Entry
When the program runs, the terminal displays:
Enter an age
You type:
25
Buffer status:
['2'] ['5'] ['\n']
Step 2: nextInt() Executes
int age = sc.nextInt();
Following the rules of token-based parsing, nextInt():
- Begins reading from the buffer
- Consumes
'2'and'5'(non-delimiter characters) - Encounters
'\n', which is a delimiter - Stops reading but does not consume the delimiter
- Parses the token
"25"into the integer value25 - Returns
25to the program
int age = 25;
Buffer status:
['\n']
The line feed remains in the buffer.
Step 3: Prompt Appears
The terminal now shows:
Enter an age
25
Enter a name
Misconception: You might expect the program to pause here and wait for you to type Ahi.
Reality: The program pauses only if the buffer is empty.
Step 4: nextLine() Executes
String name = sc.nextLine();
Following the rules of line-based parsing, nextLine():
- Checks the buffer
- Immediately detects
'\n' - Consumes and discards the line feed
- Returns everything before
'\n'
There were no characters before it.
Therefore, it returns an empty string.
String name = "";
Step 5: Final Output
System.out.println("Name: " + name);
System.out.println("Age: " + age);
Output:
Name:
Age: 25
Solution
Now you understand where the problem occurred and why. Let us fix it.
There are several ways to solve this.
1. The Quick Fix
Add an extra nextLine() immediately after nextInt() to clear the buffer.
System.out.println("Enter an age");
int age = sc.nextInt();
sc.nextLine(); // Consumes and discards the leftover '\n'
System.out.println("Enter a name");
String name = sc.nextLine();
Why It Works
-
nextInt()leaves the line feed character ('\n') in the input buffer. - The additional
nextLine()consumes that'\n'and removes it. - Now, when the second
nextLine()executes, the buffer is clean, so the program waits for your name input.
2. The Professional Approach
Avoid mixing token-based and line-based parsing.
Instead, read all input using nextLine() and convert numeric values explicitly using parsing methods such as Integer.parseInt().
This method takes a numeric string (for example, "25") and converts it into a primitive int value (25).
System.out.println("Enter an age:");
int age = Integer.parseInt(sc.nextLine());
System.out.println("Enter a name:");
String name = sc.nextLine();
Why It Works
-
nextLine()consumes the line feed character each time it reads input. - No delimiters remain in the buffer.
- Parsing explicitly using methods such as
Integer.parseInt()gives you greater control over input handling.
Other Parsing Methods
Double.parseDouble()Float.parseFloat()Long.parseLong()Boolean.parseBoolean()
3. The Duct Tape Fix
Reverse the order of the inputs.
System.out.println("Enter a name");
String name = sc.nextLine();
System.out.println("Enter an age");
int age = sc.nextInt();
Why This Is Wrong
nextInt() still leaves '\n' in the input buffer.
If the program later requires another call to nextLine(), the same issue will immediately reappear.
Conclusion
Now you understand the whys, the hows, the dos, and the don’ts.
In Java, nothing is broken. The behaviour is defined. The rules are strict. The machine is consistent.
Use that consistency to your advantage rather than fighting against it.
Try This Yourself
Scanner sc = new Scanner(System.in);
System.out.println("Enter your full name:");
String firstName = sc.next();
String lastName = sc.next();
System.out.println("Hello " + firstName + " " + lastName);
Input:
Aditya Sinha
Output:
Hello Aditya Sinha
Pause and think:
- Why does this work?
- How does
next()decide where to stop reading? - What remains in the input buffer afterwards?
- What happens if the name has more than two parts?
Glossary: Short and Simple
Buffer
When data is being transferred from a source (Point A) to a destination (Point B), it is temporarily stored in a small memory area between them called a buffer.
It serves as a waiting room for data and typically follows the FIFO (First In, First Out) principle.
Input Buffer:
- Source: Keyboard
- Destination: Java program
Internally, the data passes through multiple layers before reaching the Java program.
Token
A token is a continuous sequence of non-delimiter characters.
Token formation is the internal act of grouping characters together until a delimiter is found.
Example buffer:
['2']['5'][' ']['A']['h']['i']
Tokens formed:
"25"
"Ahi"
Parsing
When you type:
25
Internally (represented in binary form):
'2' -> ASCII value 50
'5' -> ASCII value 53
'\n' -> ASCII value 10
At this stage, the computer does not recognise the integer 25.
It only sees the sequence of characters '2', '5', and '\n'.
Inside nextInt():
['2','5','\n'] -> "25"
A String token "25" is formed.
The actual parsing:
- Checks if
"25"is a valid integer - Converts it into the numeric value
25
"25" -> before parsing (String)
25 -> after parsing (int)
The integer value is then returned to the program.
Parsing here simply means converting characters into a meaningful data type.
This is different from compiler parsing, which analyses the grammatical structure of an entire program.
In both cases, however, the core idea remains the same: interpreting input according to defined rules.
Whitespace Character
A whitespace character has no visible symbol. It appears as blank space and is used to create horizontal or vertical separation between visible characters.
Examples:
-
' '(space) -
'\t'(tab) -
'\n'(line feed)
System.out.println("Name" + " " + "Age" + "\n" + "Ahi" + "\t" + "25");
Output:
Name Age
Ahi 25
Escape Sequence Character
An escape sequence is a special character representation used inside a string. It begins with a backslash (\).
Examples:
\n\t-
\"
System.out.println("He said, \"Hello!\"");
Output:
He said, "Hello!"
Escape sequences and whitespace characters are not the same thing.
-
\"→ Escape sequence, not whitespace -
\n→ Escape sequence and whitespace -
' '→ Whitespace, not escape sequence
Delimiter
In the context of Scanner and input processing in Java, a delimiter is a character or pattern used to separate input into smaller pieces called tokens. It marks where one token ends and the next begins like a boundary.
By default, Scanner uses whitespace characters as delimiters.
When you type:
25 Ahi
The space acts as a delimiter, and Scanner sees two tokens:
[25] [Ahi]
You can even change it using useDelimiter() method:
sc.useDelimiter(",");
Now the comma becomes the delimiter.
If the input is:
25,Ahi
The tokens will be:
[25] [Ahi]
Line Terminator
A line terminator is a kind of whitespace character (also an escape sequence character) that is used to move the cursor to a new line.
Examples:
-
'\n'(Line feed) -
'\r'(Carriage return)
System.out.println("Hello\nWorld");
Output:
Hello
World



Top comments (0)