Skip to main content

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.

MethodLine BreakUse Case
System.out.println()Automatic newlineGeneral output
System.out.print()No newlineContinue 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​

SpecifierTypeDescriptionExample
%dIntegerDecimal integer%d -> 42
%oIntegerOctal integer%o -> 52
%xIntegerHexadecimal (lowercase)%x -> 2a
%XIntegerHexadecimal (uppercase)%X -> 2A
%fFloatFixed-point notation%f -> 3.140000
%eFloatScientific notation (lowercase)%e -> 3.140000e+00
%EFloatScientific notation (uppercase)%E -> 3.140000E+00
%gFloatAutomatically selects shorter form-
%sStringString%s -> "hello"
%SStringUppercase String%S -> "HELLO"
%cCharacterchar%c -> A
%bBooleanboolean%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/OptionMeaningExample
numberSpecify output width%10d -> 10-char right-aligned
-Left-align%-10d -> 10-char left-aligned
0Pad 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
.numberDecimal 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​

MethodReturn TypeDescription
next()StringRead one word up to whitespace
nextLine()StringRead a full line (until Enter)
nextInt()intRead an integer
nextLong()longRead a long integer
nextDouble()doubleRead a floating-point number
nextFloat()floatRead a float number
nextBoolean()booleanRead true/false
hasNext()booleanCheck if there is a next token
hasNextInt()booleanCheck 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();
}
}
warning

Scanner pitfalls:

  1. After nextInt(), must flush the buffer before calling nextLine()
  2. Flush buffer with: call scanner.nextLine(); one more time
  3. Alternatively, use only nextLine() and convert with Integer.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​

ItemScannerBufferedReader
SpeedSlowFast
Ease of useConvenient (type-specific methods)Cumbersome (all as String)
Exception handlingNot requiredIOException must be handled
Best forGeneral inputLarge 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 newline
  • print(): print (no newline)
  • printf(): formatted output (%d, %s, %f, %.2f, %10s, etc.)
  • Scanner: reads keyboard input, next(), nextLine(), nextInt(), nextDouble()
  • After nextInt(), be careful with nextLine(): must consume the remaining \n in the buffer
  • BufferedReader: fast input, use readLine() + parseInt() combination
  • try-with-resources: automatically closes Scanner/BufferedReader
  • System.err: stream for printing error messages