Reading input with Scanner
Read numbers, words and whole lines from the keyboard, and avoid the nextInt/nextLine trap.
Until now our programs always did the same thing. Reading input makes them interactive: a calculator that uses your numbers, a quiz that checks your answers. The standard tool for reading keyboard input in beginner programs is java.util.Scanner.
Your first interactive program#
A sample run (what you type is shown after the prompt):
Step by step:
import java.util.Scanner;makes the class available. Onlyjava.lang(home ofString,Math,System) is imported automatically.new Scanner(System.in)creates a scanner that reads from standard input, which is normally the keyboard.System.out.print(noln) prints the prompt without a newline, so the cursor waits on the same line.in.nextLine()waits until the user presses Enter and returns everything they typed on that line.
Reading different types#
Scanner splits input into tokens separated by whitespace (spaces, tabs, newlines) and can convert each token for you:
printf prints formatted text: %.2f means "a decimal number with 2 digits after the point", and %n is a newline. You will learn more format codes in the strings lesson.
Because tokens are separated by any whitespace, the user could also type 4.5 2 on one line and the program would behave the same.
Note:
nextDouble()uses your computer's locale. On systems set to, say, German, it expects4,5instead of4.5. To always accept a dot, create the scanner withnew Scanner(System.in).useLocale(java.util.Locale.US).
The nextInt() + nextLine() trap#
This is the most common Scanner bug. Try it:
When you type 30 and press Enter, the input buffer contains 30\n. nextInt() consumes 30 but leaves the \n. nextLine() then reads "everything up to the next newline", which is nothing, and returns "" without waiting.
Two reliable fixes:
Fix 2 is predictable because every read consumes exactly one line.
Validating input#
Users make typos. If they type ten where you call nextInt(), your program crashes with an InputMismatchException. Use the hasNextXxx() methods to check before reading:
With the input ten then 25:
The loop keeps discarding bad tokens until a valid integer arrives. You will meet while loops properly in two lessons; the idea here is simply "repeat until valid". Another approach, reading a line and calling Integer.parseInt inside try/catch, is covered in the exceptions lesson.
Reading until the input ends#
hasNextLine() and hasNextInt() return false when input runs out. That lets a program process any amount of data, typed or piped from a file:
When typing at the keyboard, signal "end of input" with Ctrl+D on Linux/macOS or Ctrl+Z then Enter on Windows.
A tiny tip calculator#
Putting it all together, using the line-based approach:
Closing the Scanner#
A Scanner holds a resource, so tools may warn "resource leak: in is never closed". For a scanner on System.in:
- Create one scanner for the whole program and reuse it. Creating several scanners on
System.incan lose buffered input. - Closing it also closes
System.in, after which no part of your program can read the keyboard again. In small programs it is fine to let it close when the program ends.
For scanners on files, always close them, ideally with try-with-resources, which you will learn in a later lesson.
Common mistakes#
- Forgetting
import java.util.Scanner;(error:cannot find symbol: class Scanner). - Mixing
nextInt()withnextLine()without consuming the leftover newline. - Creating a new
Scanner(System.in)inside a loop or in several methods. - Using
next()when you wanted a full line:next()stops at the first space, soNew Delhibecomes justNew.
What's next#
Your programs can now react to the user. Next we teach them to make decisions with if, else and switch.
Check your understanding
Quick quiz
1.You call
nextInt()and thennextLine(). The user typed42and pressed Enter. What doesnextLine()return?2.What happens if the user types
abcwhen your program callsscanner.nextInt()?3.Which import do you need to use
Scanner?
Finished reading?
Mark this lesson complete to track your progress.