Scanner and Basic I/O — Reading Input, Console, System Streams, and printf Formatting
In this tutorial, you will learn about Scanner and Basic I/O. We cover key concepts, practical examples, and best practices to help you master this topic.
Java's Scanner class provides flexible text Parsing for user input, while Console, System.in/out/err, and printf handle basic I/O operations. Every interactive program — from simple command-line tools to complex CLI applications — uses these facilities to communicate with the user.
What You'll Learn
- Reading input with Scanner
- Using Console for password input
- System.in, System.out, System.err
- Formatting output with printf and String.format
Why It Matters
Reading input correctly is trickier than it seems. Scanner has subtle behaviors around newlines, locales, and resource management. Understanding these prevents the common "nextLine() after nextInt()" bug.
Real-World Use
CLI tools, interactive scripts, and CI pipeline prompts all use basic I/O. Build tools (Maven, Gradle) print formatted output. printf-style formatting is used throughout logging and reporting.
The Scanner Class
Scanner reads and parses text from various input sources:
Scanner scanner = new Scanner(System.in);
System.out.print("Enter your name: ");
String name = scanner.nextLine();
System.out.println("Hello, " + name);
scanner.close();
Reading Different Types
Scanner scanner = new Scanner(System.in);
System.out.print("Enter age: ");
int age = scanner.nextInt();
System.out.print("Enter salary: ");
double salary = scanner.nextDouble();
System.out.print("Are you employed? (true/false): ");
boolean employed = scanner.nextBoolean();
System.out.print("Enter a word: ");
String word = scanner.next(); // reads one token
scanner.nextLine(); // consume the leftover newline
System.out.print("Enter full address: ");
String address = scanner.nextLine(); // reads entire line
The nextLine() Trap
Scanner scanner = new Scanner(System.in);
System.out.print("Enter age: ");
int age = scanner.nextInt(); // reads int, leaves "\n" in buffer
System.out.print("Enter name: ");
String name = scanner.nextLine(); // reads the leftover "\n", not the name!
Fix: add an extra scanner.nextLine() after nextInt() to consume the newline.
Delimiters
Scanner scanner = new Scanner("apple,banana,cherry");
scanner.useDelimiter(",");
while (scanner.hasNext()) {
System.out.println(scanner.next());
}
Reading from Files
Scanner scanner = new Scanner(Path.of("data.txt"));
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
System.out.println(line);
}
The Console Class
Console is best for password input (disables echoing):
Console console = System.console();
if (console == null) {
System.out.println("No console available (running in IDE?)");
return;
}
String username = console.readLine("Username: ");
char[] password = console.readPassword("Password: ");
System.out.println("Welcome, " + username);
// Always clear password arrays
Arrays.fill(password, ' ');
System.console() returns null when the program is run in an IDE (no terminal attached).
System.out, System.in, System.err
System.out.println("Normal output"); // stdout
System.err.println("Error output"); // stderr
int data = System.in.read(); // raw byte input
System.out and System.err are PrintStream objects. System.in is an InputStream.
Redirecting
System.setOut(new PrintStream("output.log"));
System.setErr(new PrintStream("error.log"));
printf and Formatting
Printf Syntax
System.out.printf("Hello, %s! You are %d years old.%n", name, age);
%n is the platform-independent newline.
Common Format Specifiers
| Specifier | Type | Example |
|---|---|---|
%s |
String | "Hello" |
%d |
Integer | 42 |
%f |
Float/Double | 3.141593 |
%.2f |
Float with 2 decimals | 3.14 |
%,d |
Integer with commas | 1,234,567 |
%x |
Hex | ff |
%tY |
Year (date) | 2026 |
%n |
Newline |
Examples
// Decimal precision
System.out.printf("Price: $%.2f%n", 19.99); // $19.99
// Width and alignment
System.out.printf("%-10s %5d%n", "Alice", 95);
System.out.printf("%-10s %5d%n", "Bob", 87);
// Alice 95
// Bob 87
// Comma formatting
System.out.printf("%,d%n", 1000000); // 1,000,000
// Date formatting
LocalDate today = LocalDate.now();
System.out.printf("%1$tB %1$td, %1$tY%n", today); // June 28, 2026
String.format()
String message = String.format("Hello, %s! You have %d new messages.", name, count);
Formatter Class
StringBuilder sb = new StringBuilder();
Formatter formatter = new Formatter(sb);
formatter.format("Value: %.2f", 3.14159);
System.out.println(sb); // Value: 3.14
Common Mistakes
- Not calling
close()on Scanner wrapping System.in. It is technically optional (closing System.in is unusual), but IDEs may warn. Do not close Scanner wrapping System.in if you still need input. - Forgetting to consume the newline after
nextInt(). Always callnextLine()after reading primitives to consume the leftover newline. - Assuming
System.console()is never null. In IDEs,System.console()returns null. Always check for null. - Using
%dfor floating-point values.%dis for integers. Use%ffor floating point. Wrong specifier throwsIllegalFormatConversionException. - Locale-specific number formatting.
Scanneruses the default locale — in some locales,3.14must be written as3,14. Either set locale toLocale.USor handle the input format.
Practice Questions
1. What is the difference between next() and nextLine() in Scanner?
next() reads the next token (delimited by whitespace). nextLine() reads the entire line until the newline character.
2. Why does nextInt() followed by nextLine() skip the second input?
nextInt() leaves the newline character in the buffer. nextLine() consumes that leftover newline. Add an extra nextLine() after nextInt().
3. What does System.console() return in an IDE?
null. The Console object is only available when the program is run from an interactive terminal.
4. How do you format a number with commas using printf?
System.out.printf("%,d", number) for integers, System.out.printf("%,.2f", number) for decimals.
5. Why is printf preferred over string concatenation for formatted output?
It is more readable, supports locale-aware formatting, and separates format from data.
Challenge Question:
Write a program InteractiveCalculator.java that reads arithmetic expressions from the user (e.g., "3 + 4", "10 * 2.5") and prints the result. Use Scanner with appropriate delimiters. Handle errors: invalid expressions, division by zero, and exit when the user types "quit".
FAQ
{{< faq "Can I use Scanner with a String?" "Yes: new Scanner(\"content\"). This is useful for parsing strings without creating files." >}}
Mini Project
Write a program InteractiveTodo.java that:
- Displays a menu: (1) Add task, (2) List tasks, (3) Remove task, (4) Exit
- Reads the user's choice with
Scanner - Stores tasks in an
ArrayList<String> - Uses
Consolefor password protection (ask for PIN before showing tasks) - Formats the task list with
printf(index, task name, created date) - Handles edge cases: empty list, invalid menu choice, removing non-existent index
- Loops until the user chooses Exit
What's Next
Basic I/O handles text, but numbers with precision require special care. Lesson 32 covers Math and BigDecimal — the Math class, BigInteger for arbitrary precision integers, and BigDecimal for financial calculations with precise rounding.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro