Read line with Scanner
Categories:
Mastering Line-by-Line Input with Java's Scanner Class

Learn how to effectively read and process input line by line using the java.util.Scanner
class, covering common pitfalls and best practices.
The java.util.Scanner
class is a versatile tool for parsing primitive types and strings using regular expressions. While it's commonly used for reading individual tokens (words), its ability to read entire lines of input is crucial for many applications, from command-line interfaces to file processing. This article will guide you through the proper use of Scanner
for line-based input, highlighting key methods and potential issues.
Understanding Scanner.nextLine()
The primary method for reading an entire line of input with Scanner
is nextLine()
. This method reads input until it encounters a line separator (like \n
or \r\n
), consumes that separator, and returns the rest of the line as a String
. It's important to understand that nextLine()
consumes the line separator, which can be a source of common errors when mixed with other Scanner
methods.
import java.util.Scanner;
public class ReadLineExample {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter your full name: ");
String fullName = scanner.nextLine();
System.out.println("Hello, " + fullName + "!");
System.out.print("Enter your favorite quote (press Enter when done): ");
String quote = scanner.nextLine();
System.out.println("Your quote: \"" + quote + "\"");
scanner.close();
}
}
Basic usage of Scanner.nextLine()
to read full lines of text.
Scanner
object using scanner.close()
when you are finished with it to release system resources. For Scanner
s wrapping System.in
, closing it also closes System.in
, which might not be desirable in long-running applications or if other parts of your program need to read from System.in
.The nextLine()
Trap: Mixing with next()
Methods
A very common issue arises when nextLine()
is used immediately after other Scanner
methods like nextInt()
, nextDouble()
, or next()
. These methods read a token but do not consume the trailing newline character. When nextLine()
is called subsequently, it immediately consumes this leftover newline character and returns an empty string, skipping the intended line input. This is often referred to as the 'newline trap'.
flowchart TD A[Start Program] --> B{Call nextInt()};; B --> C[User enters '123' + Enter];; C --> D{nextInt() reads '123'};; D --> E["Newline character (\n) remains in buffer"];; E --> F{Call nextLine()};; F --> G["nextLine() consumes remaining \n"];; G --> H[Returns empty string];; H --> I[Program continues, skipping intended input];; I --> J[End Program];;
Illustrating the 'newline trap' when mixing nextInt()
and nextLine()
.
import java.util.Scanner;
public class NewlineTrapExample {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter your age: ");
int age = scanner.nextInt(); // Reads integer, leaves newline
System.out.println("You are " + age + " years old.");
// PROBLEM: nextLine() will consume the leftover newline from nextInt()
System.out.print("Enter your city: ");
String city = scanner.nextLine(); // This will likely be empty!
System.out.println("Your city is: " + city);
scanner.close();
}
}
Demonstration of the newline trap, where nextLine()
reads an empty string.
Resolving the Newline Trap
The solution to the newline trap is simple: always consume the leftover newline character after calling any next()
method (e.g., nextInt()
, nextDouble()
, next()
) if you intend to call nextLine()
immediately afterward. You can do this by adding an extra scanner.nextLine()
call, which will simply discard the newline.
import java.util.Scanner;
public class NewlineTrapSolution {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter your age: ");
int age = scanner.nextInt(); // Reads integer, leaves newline
scanner.nextLine(); // Consume the leftover newline character
System.out.println("You are " + age + " years old.");
System.out.print("Enter your city: ");
String city = scanner.nextLine(); // Now this will read the actual city
System.out.println("Your city is: " + city);
scanner.close();
}
}
Corrected code to handle the newline trap by adding an extra nextLine()
call.
nextLine()
and then use a separate Scanner
instance (or String.split()
, Integer.parseInt()
, etc.) to parse the individual tokens from that line. This approach avoids mixing next()
and nextLine()
on the same Scanner
.