What's the Best Way to Read User Input in Java: Scanner Methods Compared?
Problem
When I wrote a simple Java program to collect both integer and string input, I got this strange behavior:
import java.util.Scanner;
public class InputExample { public static void main(String[] args) { Scanner scanner = new Scanner(System.in);
System.out.print("Enter your age: "); int age = scanner.nextInt(); // reads 25, leaves \n in buffer System.out.print("Enter your name: "); String name = scanner.nextLine(); // immediately reads the leftover \n
System.out.println("Age: " + age); System.out.println("Name: '" + name + "'"); // prints empty string!
scanner.close(); }}The output was:
Age: 25Name: ''The name input was completely skipped!
Environment
- Java 21
- macOS 14.5
- Standard Scanner class from java.util
What happened?
I was trying to create a simple program that asks for a user’s age (integer) and name (string). But when I mixed nextInt() and nextLine(), the second input got skipped.
Here’s what I expected to happen:
Enter your age: 25Enter your name: JohnAge: 25Name: JohnBut I got an empty string for the name instead.
How to solve it?
I tried several approaches to fix this issue.
First attempt: Buffer management
I realized that nextInt() reads the integer but leaves the newline character (\n) in the buffer. The next nextLine() consumes that leftover newline immediately.
import java.util.Scanner;
public class InputExample { public static void main(String[] args) { Scanner scanner = new Scanner(System.in);
System.out.print("Enter your age: "); int age = scanner.nextInt(); scanner.nextLine(); // consume the leftover newline
System.out.print("Enter your name: "); String name = scanner.nextLine();
System.out.println("Age: " + age); System.out.println("Name: '" + name + "'");
scanner.close(); }}This worked! The output was:
Age: 25Name: 'John'Second attempt: Use nextLine() for everything
Then I thought, what if I use nextLine() for all input and parse the integer manually?
import java.util.Scanner;
public class InputExample { public static void main(String[] args) { Scanner scanner = new Scanner(System.in);
System.out.print("Enter your age: "); int age = Integer.parseInt(scanner.nextLine());
System.out.print("Enter your name: "); String name = scanner.nextLine();
System.out.println("Age: " + age); System.out.println("Name: '" + name + "'");
scanner.close(); }}This approach also worked and gave me more control over input parsing.
Third attempt: Add validation
But what if the user enters invalid input? I added validation:
import java.util.Scanner;
public class InputExample { public static void main(String[] args) { Scanner scanner = new Scanner(System.in);
while (true) { System.out.print("Enter your age: "); String ageInput = scanner.nextLine(); try { int age = Integer.parseInt(ageInput); break; } catch (NumberFormatException e) { System.out.println("Please enter a valid number"); } }
System.out.print("Enter your name: "); String name = scanner.nextLine();
System.out.println("Age: " + age); System.out.println("Name: '" + name + "'");
scanner.close(); }}Now the program handles invalid input gracefully.
The reason
I think the key reason for the input skipping problem is that Scanner uses an internal buffer to read input. When you call:
nextInt()- reads characters until it finds an integer, but leaves the delimiter (newline) in the buffernextLine()- reads everything until the next newline character, including any leftover newlines
So when you call nextInt() followed by nextLine(), the nextLine() immediately consumes the newline that was left after nextInt().
Summary
In this post, I showed how to resolve the Scanner input skipping problem in Java. The key point is understanding that Scanner methods have different behaviors regarding buffer handling.
Here’s what I learned:
nextInt()leaves the newline character in the buffernextLine()consumes the entire line including any leftover newlines- You can either manage the buffer manually or use
nextLine()+ parsing for better control - Always add input validation to handle invalid user input
The best approach depends on your needs:
- Use
nextInt()alone when only integers are needed - Use
nextLine()+ parsing for mixed input scenarios - Always flush the buffer when switching between input types
- Add validation to make your code more robust
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments