00:00

Scanner Class in Java – Reading Input from Users, Strings and Files

Last updated:

java.util.Scanner reads text input and breaks it into tokens that can be converted to numbers, booleans or strings. It is the easiest way to read keyboard input in console programs, and it can also read from strings, files and other streams.

This tutorial covers reading user input, the difference between next() and nextLine(), the famous newline trap, validating input with hasNextXxx(), custom delimiters and files, and when to use BufferedReader instead.

1. Reading Keyboard Input

Create a Scanner on System.in and call the method for the type you expect. The output below was produced with the sample input Asha Rao, 29 and 1.68, each typed on its own line:

ReadUserInput.java
import java.util.Scanner;

public class ReadUserInput {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        System.out.print("Enter your name: ");
        String name = sc.nextLine();                  // whole line

        System.out.print("Enter your age: ");
        int age = sc.nextInt();                       // a token parsed as int

        System.out.print("Enter your height in metres: ");
        double height = sc.nextDouble();

        System.out.println();
        System.out.println("Hello " + name + ", you are " + age + " and " + height + " m tall.");
        // Do not close a Scanner wrapping System.in if other code still needs to read from it
    }
}
Output (with sample input)
Enter your name: Enter your age: Enter your height in metres: 
Hello Asha Rao, you are 29 and 1.68 m tall.
MethodReads
next()The next token (up to whitespace)
nextLine()The rest of the current line, without the line separator
nextInt(), nextLong(), nextDouble(), nextBoolean()…A token parsed as that type
hasNext(), hasNextInt(), hasNextLine()…Whether such input is available, without consuming it
useDelimiter(pattern)Change the token separator (default: whitespace)
close()Close the scanner and its source

2. The nextInt() + nextLine() Trap

nextInt() reads the number but leaves the newline after it. A following nextLine() then returns that empty remainder immediately. Sample input: 3, Wireless Mouse, 5, USB Keyboard:

NextLineTrap.java
import java.util.Scanner;

public class NextLineTrap {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        System.out.print("Quantity: ");
        int qty = sc.nextInt();               // leaves the newline in the buffer
        System.out.print("Product (buggy): ");
        String product = sc.nextLine();        // reads that leftover empty line!
        System.out.println();
        System.out.println("qty=" + qty + ", product='" + product + "'");
        System.out.println("(the product name is still waiting: '" + sc.nextLine() + "')");

        System.out.print("Quantity: ");
        qty = sc.nextInt();
        sc.nextLine();                         // FIX: consume the rest of the line
        System.out.print("Product (fixed): ");
        product = sc.nextLine();
        System.out.println();
        System.out.println("qty=" + qty + ", product='" + product + "'");
    }
}
Output (with sample input)
Quantity: Product (buggy): 
qty=3, product=''
(the product name is still waiting: 'Wireless Mouse')
Quantity: Product (fixed): 
qty=5, product='USB Keyboard'

The fix is to call sc.nextLine() once after reading a number, or to read every line with nextLine() and parse it with Integer.parseInt(line.trim()).

3. Validating Input

If the input does not match the expected type, nextInt() throws InputMismatchException. Check with hasNextInt() first. Sample input: 78 91 abc, 150 66, done:

ValidateInput.java
import java.util.Scanner;

public class ValidateInput {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int total = 0, count = 0;
        System.out.println("Enter marks (type 'done' to finish):");
        while (sc.hasNext()) {
            if (sc.hasNextInt()) {                      // check before reading
                int m = sc.nextInt();
                if (m < 0 || m > 100) { System.out.println("  ignored out-of-range value " + m); continue; }
                total += m; count++;
            } else {
                String word = sc.next();
                if (word.equalsIgnoreCase("done")) break;
                System.out.println("  '" + word + "' is not a number");
            }
        }
        System.out.println("count = " + count + ", average = " + (count == 0 ? 0 : total / (double) count));
    }
}
Output (with sample input)
Enter marks (type 'done' to finish):
  'abc' is not a number
  ignored out-of-range value 150
count = 3, average = 78.33333333333333

4. Strings, Delimiters and Files

A scanner can read any text source and split on any regular expression:

ScanStringsAndFiles.java
import java.io.IOException;
import java.nio.file.*;
import java.util.Scanner;

public class ScanStringsAndFiles {
    public static void main(String[] args) throws IOException {
        // Scanning a String with a custom delimiter
        try (Scanner sc = new Scanner("Asha;29;Pune").useDelimiter(";")) {
            System.out.println("name=" + sc.next() + ", age=" + sc.nextInt() + ", city=" + sc.next());
        }

        // Scanning a file line by line
        Path file = Path.of(System.getProperty("java.io.tmpdir"), "orders.txt");
        Files.writeString(file, "A-17,2499\nB-42,799\nC-99,1299\n");
        double sum = 0;
        try (Scanner sc = new Scanner(file)) {
            while (sc.hasNextLine()) {
                String[] parts = sc.nextLine().split(",");
                sum += Double.parseDouble(parts[1]);
            }
        }
        System.out.println("order total = " + sum);
        Files.delete(file);
    }
}
Output
name=Asha, age=29, city=Pune
order total = 4597.0

Use try-with-resources to close scanners on files and strings. Avoid closing a scanner on System.in while the program still needs keyboard input, because closing it also closes System.in.

5. Scanner vs BufferedReader

AspectScannerBufferedReader
ParsingBuilt-in (nextInt, nextDouble)Manual (Integer.parseInt)
SpeedSlower (regex-based)Much faster for large input
Buffer1 KB8 KB by default
ExceptionsUnchecked (InputMismatchException)Checked IOException
Thread-safeNoYes
Best forInteractive console programs, small inputsLarge files, competitive programming

6. Summary

  • Scanner reads tokens from System.in, strings, files and streams and parses them into types.
  • next() reads a token; nextLine() reads the rest of the line.
  • After nextInt() and similar methods, consume the leftover newline before calling nextLine().
  • Use hasNextXxx() to validate input and avoid InputMismatchException.
  • Use BufferedReader for large or performance-sensitive input.

Related Tutorials