Ch 2.6 Console Input and Output (I/O)
So far, we have printed information by directly assigning values to variables. In this chapter, we learn how to print output in a desired format and conversely, how to read values typed by the user on the keyboard and store them in variables.
1. Comparing Three Output Methodsā
Java provides three ways to print to the console.
| Method | Line Break | Use Case |
|---|---|---|
System.out.println() | Automatic newline | General output |
System.out.print() | No newline | Continue printing on the same line |
System.out.printf() | None (\n must be added manually) | Formatted output |
public class OutputMethods {
public static void main(String[] args) {
// println: prints and automatically adds a newline
System.out.println("First line");
System.out.println("Second line");
System.out.println(); // Print blank line
// print: prints without a newline
System.out.print("A");
System.out.print("B");
System.out.print("C");
System.out.println(); // Add newline
// printf: formatted output
System.out.printf("Name: %s, Age: %d%n", "Alice", 20);
// %n is a platform-independent newline (same as \n but more portable)
}
}
Output:
First line
Second line
ABC
Name: Alice, Age: 20
2. Complete Guide to printf and Format Specifiersā
printf is a formatted output method originating from the C language. It is used by placing a type character after the % symbol.
Basic Format Specifiersā
| Specifier | Type | Description | Example |
|---|---|---|---|
%d | Integer | Decimal integer | %d -> 42 |
%o | Integer | Octal integer | %o -> 52 |
%x | Integer | Hexadecimal (lowercase) | %x -> 2a |
%X | Integer | Hexadecimal (uppercase) | %X -> 2A |
%f | Float | Fixed-point notation | %f -> 3.140000 |
%e | Float | Scientific notation (lowercase) | %e -> 3.140000e+00 |
%E | Float | Scientific notation (uppercase) | %E -> 3.140000E+00 |
%g | Float | Automatically selects shorter form | - |
%s | String | String | %s -> "hello" |
%S | String | Uppercase String | %S -> "HELLO" |
%c | Character | char | %c -> A |
%b | Boolean | boolean | %b -> true |
%n | - | Newline (platform-independent) | - |
%% | - | The % character itself | %% -> % |
public class PrintfBasic {
public static void main(String[] args) {
int intVal = 42;
double dblVal = 3.14;
String strVal = "Java";
char charVal = 'J';
boolean boolVal = true;
System.out.printf("Integer: %d%n", intVal);
System.out.printf("Octal: %o%n", intVal);
System.out.printf("Hex (lower): %x%n", intVal);
System.out.printf("Hex (upper): %X%n", intVal);
System.out.printf("Float: %f%n", dblVal);
System.out.printf("Scientific: %e%n", dblVal);
System.out.printf("String: %s%n", strVal);
System.out.printf("Uppercase: %S%n", strVal);
System.out.printf("Char: %c%n", charVal);
System.out.printf("Boolean: %b%n", boolVal);
System.out.printf("Percent: 50%%%n");
}
}
Output:
Integer: 42
Octal: 52
Hex (lower): 2a
Hex (upper): 2A
Float: 3.140000
Scientific: 3.140000e+00
String: Java
Uppercase: JAVA
Char: J
Boolean: true
Percent: 50%
3. printf Flags, Width, and Precisionā
You can fine-tune the output format by adding extra options to format specifiers.
Syntax: %[flags][width][.precision]typeā
| Flag/Option | Meaning | Example |
|---|---|---|
number | Specify output width | %10d -> 10-char right-aligned |
- | Left-align | %-10d -> 10-char left-aligned |
0 | Pad empty spaces with zeros | %010d -> 0000000042 |
+ | Always show sign | %+d -> +42 or -42 |
| Space before positive numbers | % d -> 42 |
, | Thousands separator | %,d -> 1,000,000 |
.number | Decimal places | %.2f -> 3.14 |
public class PrintfFlags {
public static void main(String[] args) {
int num = 42;
double d = 3.14159;
long big = 1_000_000;
// Width (right-aligned by default)
System.out.printf("[%10d]%n", num); // [ 42]
System.out.printf("[%-10d]%n", num); // [42 ]
// Zero padding
System.out.printf("[%010d]%n", num); // [0000000042]
// Sign display
System.out.printf("[%+d]%n", num); // [+42]
System.out.printf("[%+d]%n", -num); // [-42]
// Thousands separator
System.out.printf("[%,d]%n", big); // [1,000,000]
// Decimal places
System.out.printf("[%.2f]%n", d); // [3.14]
System.out.printf("[%.5f]%n", d); // [3.14159]
System.out.printf("[%10.2f]%n", d); // [ 3.14]
System.out.printf("[%-10.2f]%n", d); // [3.14 ]
// Table format example
System.out.printf("%-15s %5s %8s%n", "Name", "Age", "Score");
System.out.printf("%-15s %5d %8.2f%n", "Alice Java", 20, 95.5);
System.out.printf("%-15s %5d %8.2f%n", "Bob Python", 22, 88.3);
System.out.printf("%-15s %5d %8.2f%n", "Carol Sharp", 21, 92.1);
}
}
Output:
[ 42]
[42 ]
[0000000042]
[+42]
[-42]
[1,000,000]
[3.14]
[3.14159]
[ 3.14]
[3.14 ]
Name Age Score
Alice Java 20 95.50
Bob Python 22 88.30
Carol Sharp 21 92.10
4. Scanner Class in Detailā
Scanner is the most basic way to read keyboard input. You must declare import java.util.Scanner; before using it.
Main Scanner Methodsā
| Method | Return Type | Description |
|---|---|---|
next() | String | Read one word up to whitespace |
nextLine() | String | Read a full line (until Enter) |
nextInt() | int | Read an integer |
nextLong() | long | Read a long integer |
nextDouble() | double | Read a floating-point number |
nextFloat() | float | Read a float number |
nextBoolean() | boolean | Read true/false |
hasNext() | boolean | Check if there is a next token |
hasNextInt() | boolean | Check if the next token is an int |
import java.util.Scanner;
public class ScannerMethods {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Reading various types of input
System.out.print("Enter name: ");
String name = scanner.nextLine(); // Reads the full line
System.out.print("Enter age: ");
int age = scanner.nextInt(); // Reads only the integer
System.out.print("Enter height: ");
double height = scanner.nextDouble(); // Reads a floating-point number
System.out.printf("Name: %s, Age: %d, Height: %.1f cm%n",
name, age, height);
scanner.close();
}
}
5. Scanner Pitfall: nextLine After nextIntā
nextInt(), nextDouble(), etc. read only the number and leave the newline character (\n) in the buffer. When nextLine() is called afterward, it reads the remaining \n and returns an empty string.
import java.util.Scanner;
public class ScannerPitfall {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter age: ");
int age = scanner.nextInt(); // Input "25\n" -> reads 25, \n remains in buffer
// Problem occurs!
// System.out.print("Enter name: ");
// String name = scanner.nextLine(); // Reads \n and returns empty string!
// Solution 1: Consume remaining \n with an empty nextLine() call
scanner.nextLine(); // Consume the \n left in buffer
System.out.print("Enter name: ");
String name = scanner.nextLine(); // Now works correctly
System.out.printf("Name: %s, Age: %d%n", name, age);
scanner.close();
}
}
Scanner pitfalls:
- After
nextInt(), must flush the buffer before callingnextLine() - Flush buffer with: call
scanner.nextLine();one more time - Alternatively, use only
nextLine()and convert withInteger.parseInt()
Safer Approach: nextLine + parseInt Combinationā
import java.util.Scanner;
public class ScannerSafeMethod {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Read all input with nextLine(), convert when needed
System.out.print("Enter name: ");
String name = scanner.nextLine();
System.out.print("Enter age: ");
int age = Integer.parseInt(scanner.nextLine().trim());
System.out.print("Enter height: ");
double height = Double.parseDouble(scanner.nextLine().trim());
System.out.printf("Name: %s, Age: %d, Height: %.1f cm%n",
name, age, height);
scanner.close();
}
}
6. Repeated Input Using hasNextā
import java.util.Scanner;
public class ScannerLoop {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int sum = 0;
int count = 0;
System.out.println("Enter numbers (stop: blank line):");
// hasNextInt(): check if the next input is an integer
while (scanner.hasNextInt()) {
int num = scanner.nextInt();
sum += num;
count++;
System.out.println(" Input: " + num + " (sum: " + sum + ")");
}
if (count > 0) {
System.out.printf("Total %d numbers, Sum: %d, Average: %.2f%n",
count, sum, (double) sum / count);
}
scanner.close();
}
}
7. Fast Input Using BufferedReaderā
In competitive programming or large data processing, BufferedReader is much faster than Scanner.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class BufferedReaderExample {
public static void main(String[] args) throws IOException {
// BufferedReader can throw IOException, so exception handling is required
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Enter name: ");
String name = br.readLine(); // Read one line
System.out.print("Enter age: ");
int age = Integer.parseInt(br.readLine().trim()); // Convert to integer
System.out.print("Enter height: ");
double height = Double.parseDouble(br.readLine().trim());
System.out.printf("Name: %s, Age: %d, Height: %.1f cm%n",
name, age, height);
br.close();
}
}
Scanner vs BufferedReader Comparisonā
| Item | Scanner | BufferedReader |
|---|---|---|
| Speed | Slow | Fast |
| Ease of use | Convenient (type-specific methods) | Cumbersome (all as String) |
| Exception handling | Not required | IOException must be handled |
| Best for | General input | Large data, algorithms |
8. System.err and System.inā
public class SystemStreams {
public static void main(String[] args) {
// System.out: standard output stream (console screen)
System.out.println("Normal output");
// System.err: standard error stream (usually displayed in red in the console)
System.err.println("Error message!"); // Used for errors or warnings
// System.in: standard input stream (keyboard)
// Used by Scanner and BufferedReader
System.out.println("System.in type: " + System.in.getClass().getName());
// Error output usage example
int divisor = 0;
if (divisor == 0) {
System.err.println("[ERROR] Divisor is 0!");
} else {
System.out.println("Result: " + (10 / divisor));
}
}
}
9. Closing Scanner with try-with-resourcesā
Resources (Scanner, BufferedReader, etc.) must be closed after use. Using the try-with-resources syntax closes them automatically.
import java.util.Scanner;
public class TryWithResources {
public static void main(String[] args) {
// try-with-resources: automatically calls scanner.close() when block ends
try (Scanner scanner = new Scanner(System.in)) {
System.out.print("Enter name: ");
String name = scanner.nextLine();
System.out.print("Enter age: ");
int age = Integer.parseInt(scanner.nextLine().trim());
System.out.printf("Hello, %s! (Age: %d)%n", name, age);
} catch (NumberFormatException e) {
System.err.println("Age must be a number: " + e.getMessage());
}
// At this point, scanner has been automatically closed
}
}
10. Practical Example: Student Information Input Programā
import java.util.Scanner;
public class StudentInfoInput {
public static void main(String[] args) {
try (Scanner scanner = new Scanner(System.in)) {
System.out.println("āāāāāāāāāāāāāāāāāāāāāāāāāāāāāā");
System.out.println("ā Student Information System ā");
System.out.println("āāāāāāāāāāāāāāāāāāāāāāāāāāāāāā");
// Basic information input
System.out.print("Name: ");
String name = scanner.nextLine().trim();
System.out.print("Student ID: ");
String studentId = scanner.nextLine().trim();
System.out.print("Age: ");
int age = Integer.parseInt(scanner.nextLine().trim());
System.out.print("Major: ");
String major = scanner.nextLine().trim();
// Subject score input
System.out.println("\nEnter subject scores (0~100):");
System.out.print("Math: ");
int math = Integer.parseInt(scanner.nextLine().trim());
System.out.print("English: ");
int english = Integer.parseInt(scanner.nextLine().trim());
System.out.print("Science: ");
int science = Integer.parseInt(scanner.nextLine().trim());
// Calculations
int total = math + english + science;
double average = (double) total / 3;
// Grade calculation
char grade;
if (average >= 90) grade = 'A';
else if (average >= 80) grade = 'B';
else if (average >= 70) grade = 'C';
else if (average >= 60) grade = 'D';
else grade = 'F';
// Result output
System.out.println();
System.out.println("āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā");
System.out.printf("ā %-33sā%n", "Report Card");
System.out.println("ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā£");
System.out.printf("ā Name: %-21sā%n", name);
System.out.printf("ā Student ID: %-21sā%n", studentId);
System.out.printf("ā Age: %-21sā%n", age);
System.out.printf("ā Major: %-21sā%n", major);
System.out.println("ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā£");
System.out.printf("ā Math: %3d%22sā%n", math, "");
System.out.printf("ā English: %3d%22sā%n", english, "");
System.out.printf("ā Science: %3d%22sā%n", science, "");
System.out.println("ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā£");
System.out.printf("ā Total: %3d Average: %5.2f Grade: %c ā%n",
total, average, grade);
System.out.println("āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā");
} catch (NumberFormatException e) {
System.err.println("Scores must be numbers!");
}
}
}
Sample Input/Output:
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā Student Information System ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
Name: Alice Java
Student ID: 20240001
Age: 20
Major: Computer Science
Enter subject scores (0~100):
Math: 92
English: 85
Science: 88
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā Report Card ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā£
ā Name: Alice Java ā
ā Student ID: 20240001 ā
ā Age: 20 ā
ā Major: Computer Science ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā£
ā Math: 92 ā
ā English: 85 ā
ā Science: 88 ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā£
ā Total: 265 Average: 88.33 Grade: B ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
11. I/O Format Quick Reference Cheat Sheetā
public class CheatSheet {
public static void main(String[] args) {
// Commonly used printf patterns
int n = 42;
double d = 3.14159;
String s = "Java";
// Integer output
System.out.printf("%d%n", n); // 42
System.out.printf("%5d%n", n); // [ 42] right-aligned
System.out.printf("%-5d%n", n); // [42 ] left-aligned
System.out.printf("%05d%n", n); // [00042] zero padding
System.out.printf("%,d%n", 1000000); // 1,000,000 thousands separator
// Float output
System.out.printf("%.2f%n", d); // 3.14
System.out.printf("%8.2f%n", d); // [ 3.14]
System.out.printf("%-8.2f%n", d); // [3.14 ]
System.out.printf("%e%n", d); // 3.141590e+00
// String output
System.out.printf("%s%n", s); // Java
System.out.printf("%10s%n", s); // [ Java]
System.out.printf("%-10s%n", s); // [Java ]
System.out.printf("%.3s%n", s); // Jav (max 3 characters)
}
}
Summaryā
println(): print + automatic newlineprint(): print (no newline)printf(): formatted output (%d,%s,%f,%.2f,%10s, etc.)- Scanner: reads keyboard input,
next(),nextLine(),nextInt(),nextDouble() - After
nextInt(), be careful withnextLine(): must consume the remaining\nin the buffer - BufferedReader: fast input, use
readLine()+parseInt()combination - try-with-resources: automatically closes Scanner/BufferedReader
- System.err: stream for printing error messages