☕ Java

Scanner Class

The Scanner class (java.util.Scanner) is the standard way to read user input from the keyboard in Java. It wraps System.in and provides methods to parse tokens as specific types — nextInt(), nextDouble(), nextLine(), next() — without manually converting strings. Scanner also works with files and strings as input sources.

Creating a Scanner and Basic Reading

Scanner must be imported from java.util. For keyboard input, wrap System.in. Scanner reads tokens separated by whitespace (spaces, tabs, newlines) by default. Each next() or nextXxx() call reads the next token and advances the internal cursor. The Scanner should be closed when no longer needed, though closing System.in should be done carefully as it cannot be reopened.
Java
import java.util.Scanner;

public class BasicInput {
    public static void main(String[] args) {

        // ── Create Scanner for keyboard input: ───────────────────────
        Scanner scanner = new Scanner(System.in);

        // ── Read a String token (one word): ───────────────────────────
        System.out.print("Enter your name: ");
        String name = scanner.next();           // reads one word
        System.out.println("Hello, " + name);

        // ── Read an integer: ──────────────────────────────────────────
        System.out.print("Enter your age: ");
        int age = scanner.nextInt();
        System.out.println("Age: " + age);

        // ── Read a double: ────────────────────────────────────────────
        System.out.print("Enter your height (m): ");
        double height = scanner.nextDouble();
        System.out.printf("Height: %.2f m%n", height);

        // ── Read a boolean: ───────────────────────────────────────────
        System.out.print("Active? (true/false): ");
        boolean active = scanner.nextBoolean();
        System.out.println("Active: " + active);

        // ── Read a full line: ─────────────────────────────────────────
        scanner.nextLine();     // consume leftover newline after nextBoolean()
        System.out.print("Enter your address: ");
        String address = scanner.nextLine();    // reads entire line
        System.out.println("Address: " + address);

        // ── Close scanner when done: ──────────────────────────────────
        scanner.close();
    }
}

// ── Input/Output example: ─────────────────────────────────────────────
// Enter your name: Alice
// Hello, Alice
// Enter your age: 30
// Age: 30
// Enter your height (m): 1.68
// Height: 1.68 m
// Active? (true/false): true
// Active: true
// Enter your address: 123 Main Street
// Address: 123 Main Street

Scanner Methods Reference

Scanner provides a next method for each primitive type plus String. Each method has a corresponding hasNextXxx method that checks whether the next token can be read as that type without consuming it — essential for loops and validation.
Java
Scanner sc = new Scanner(System.in);

// ── Reading methods: ──────────────────────────────────────────────────
String  word   = sc.next();           // next whitespace-delimited token
String  line   = sc.nextLine();       // entire line including spaces
int     i      = sc.nextInt();        // next token as int
long    l      = sc.nextLong();       // next token as long
double  d      = sc.nextDouble();     // next token as double
float   f      = sc.nextFloat();      // next token as float
boolean b      = sc.nextBoolean();    // next token as boolean (true/false)
byte    by     = sc.nextByte();       // next token as byte
short   s      = sc.nextShort();      // next token as short

// ── Checking methods (non-consuming): ────────────────────────────────
boolean hasToken   = sc.hasNext();         // any token available?
boolean hasLine    = sc.hasNextLine();     // any line available?
boolean hasInt     = sc.hasNextInt();      // next token parseable as int?
boolean hasDouble  = sc.hasNextDouble();   // next token parseable as double?
boolean hasBool    = sc.hasNextBoolean();  // next token true or false?

// ── Validated input loop — keep asking until valid int: ───────────────
Scanner scanner = new Scanner(System.in);
int number = 0;

while (true) {
    System.out.print("Enter an integer: ");
    if (scanner.hasNextInt()) {
        number = scanner.nextInt();
        break;
    } else {
        System.out.println("Invalid — please enter a whole number.");
        scanner.next();     // discard the invalid token
    }
}
System.out.println("You entered: " + number);

// ── Read until end of input (file or piped input): ────────────────────
Scanner sc2 = new Scanner(System.in);
while (sc2.hasNextLine()) {
    String inputLine = sc2.nextLine();
    System.out.println("Read: " + inputLine);
}

// ── Read multiple values on one line: ────────────────────────────────
// Input: "Alice 30 1.68"
Scanner sc3 = new Scanner(System.in);
String  n = sc3.next();
int     a = sc3.nextInt();
double  h = sc3.nextDouble();
System.out.printf("%s is %d years old and %.2fm tall%n", n, a, h);

The nextLine() After nextInt() Problem

The most common Scanner pitfall occurs when mixing nextInt() (or any nextXxx() for primitives) with nextLine(). The nextInt() method reads the integer but leaves the newline character in the buffer. The immediately following nextLine() then reads that leftover newline instead of the next line of user input, returning an empty string. The fix is to call nextLine() once after nextInt() to consume the leftover newline before reading the next line.
Java
// ── The problem: nextLine() returns empty string: ────────────────────
Scanner sc = new Scanner(System.in);

System.out.print("Enter age: ");
int age = sc.nextInt();
// User types: 25
// Buffer after nextInt(): "
"  ← leftover newline

System.out.print("Enter name: ");
String name = sc.nextLine();
// nextLine() reads up to the next 
 — finds the leftover 
 immediately
// Returns "" (empty string) without waiting for user input!

System.out.println("Age: " + age);
System.out.println("Name: '" + name + "'");
// Output:
// Enter age: 25
// Enter name:          ← skipped! user never got to type
// Age: 25
// Name: ''             ← empty!

// ── Fix 1: consume leftover newline with an extra nextLine(): ─────────
Scanner sc2 = new Scanner(System.in);

System.out.print("Enter age: ");
int age2 = sc2.nextInt();
sc2.nextLine();                 // consume the leftover "
"

System.out.print("Enter name: ");
String name2 = sc2.nextLine(); // now reads correctly
System.out.println("Age: " + age2 + ", Name: " + name2);

// ── Fix 2: read everything as lines, then parse: ──────────────────────
Scanner sc3 = new Scanner(System.in);

System.out.print("Enter age: ");
int age3 = Integer.parseInt(sc3.nextLine().trim());

System.out.print("Enter name: ");
String name3 = sc3.nextLine();   // no problem — only using nextLine()

System.out.println("Age: " + age3 + ", Name: " + name3);

// ── Rule of thumb: ────────────────────────────────────────────────────
// Mixing nextInt()/nextDouble()/etc. with nextLine() in sequence
// always requires an extra nextLine() call in between.
// OR — use only nextLine() for all input and parse manually.

Scanner with Files and Strings

Scanner is not limited to keyboard input. It can read from files, strings, and any InputStream. Reading from a file with Scanner is convenient for small files where token-based or line-by-line parsing is needed. Reading from a String is useful in tests and when parsing already-loaded content.
Java
import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;

// ── Scanner reading from a file: ─────────────────────────────────────
// data.txt contents:
// Alice 95
// Bob 87
// Charlie 72

try (Scanner fileScanner = new Scanner(new File("data.txt"))) {
    while (fileScanner.hasNextLine()) {
        String studentName  = fileScanner.next();
        int    studentScore = fileScanner.nextInt();
        System.out.printf("%-10s → %d%n", studentName, studentScore);
    }
} catch (FileNotFoundException e) {
    System.err.println("File not found: " + e.getMessage());
}
// Output:
// Alice      → 95
// Bob        → 87
// Charlie    → 72

// ── Scanner with file using Path (Java 11+): ──────────────────────────
try (Scanner sc = new Scanner(Path.of("data.txt"))) {
    while (sc.hasNextLine()) {
        System.out.println(sc.nextLine());
    }
} catch (IOException e) {
    System.err.println("I/O error: " + e.getMessage());
}

// ── Scanner reading from a String: ───────────────────────────────────
String data = "10 20 30 40 50";
Scanner strScanner = new Scanner(data);

int sum = 0;
while (strScanner.hasNextInt()) {
    sum += strScanner.nextInt();
}
System.out.println("Sum: " + sum);   // Sum: 150
strScanner.close();

// ── Scanner with custom delimiter: ────────────────────────────────────
// Parse CSV line: "Alice,30,Engineer"
String csv = "Alice,30,Engineer";
Scanner csvScanner = new Scanner(csv).useDelimiter(",");

String csvName = csvScanner.next();    // Alice
int    csvAge  = csvScanner.nextInt(); // 30
String csvJob  = csvScanner.next();    // Engineer
System.out.printf("%s (%d) — %s%n", csvName, csvAge, csvJob);
csvScanner.close();