Java User Input: Reading Data from Keyboard with System.in and Scanner
1. Reading Input with System.in
To allow users to enter input from the keyboard, Java provides a standard input stream, represented by the System.in object. Let's explore how it works.
For reading user input from the keyboard in Java, the System.in.read() method is used—it returns the code of the entered character. When executed, the JVM pauses the program and waits for the user to input a character. To display the character on the console, it is cast to the char type:
public class SystemInExample {
public static void main(String[] args) throws IOException {
int x = System.in.read();
char c = (char) x;
System.out.println("Character code: " + c + " = " + x);
}
} 2. The Scanner Class
Of course, using System.in directly is inconvenient when you need to input more than one character. In such cases, the Scanner class can be used. This class is located in the java.util package, so it must be imported:
import java.util.Scanner; The methods of this class allow reading a string, an int value, or a double value.
Scanner Class Methods:
-
hasNextInt() - returns true if an integer can be read from the input stream.
-
nextInt() - reads an integer from the input stream.
-
hasNextDouble() - checks if a double-precision floating-point number can be read from the input stream.
-
nextDouble() - reads a double-precision floating-point number from the input stream.
-
nextLine() - reads an entire sequence of characters, i.e., a string.
-
hasNext() - checks if there are any characters left in the input stream.
3. Reading Numbers: nextInt() and hasNextInt()
In the following example, the hasNextInt() method checks if the user has entered an integer. If so, the nextInt() method reads the input. If the user enters a string, the program will output "You did not enter an integer" to the console:
import java.util.Scanner;
public class ScannerExample1 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter an integer: ");
if (scanner.hasNextInt()) {
int i = scanner.nextInt();
System.out.println(i);
} else {
System.out.println("You did not enter an integer");
}
}
} Important note
If you call nextLine() right after nextInt() (or nextDouble()), it reads an empty string. That's because nextInt() reads only the number but leaves the newline character (\n) from your Enter key in the buffer. The next nextLine() immediately hits that \n and returns an empty string. To work around this, add an extra "throwaway" nextLine() after nextInt() to consume the leftover newline:
int age = scanner.nextInt();
scanner.nextLine(); // consume the leftover newline after the number
String name = scanner.nextLine(); // now the line is read correctly 4. Reading Decimals: nextDouble()
Now, let's see an example using the nextDouble() method to read a floating-point number. If the user enters a string, the program will crash with a runtime error. To avoid this, check the input using hasNextDouble() before calling nextDouble():
import java.util.Scanner;
public class ScannerExample2 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// If you enter 's', a runtime error will occur
double i = scanner.nextDouble();
System.out.println(i);
}
} Watch out for the locale.
The nextDouble() method uses the decimal separator defined by the system's locale. In many European locales the separator is a comma (3,14), while in the US and UK it's a period (3.14). If the input format doesn't match the locale, nextDouble() throws an InputMismatchException. To make Scanner always expect a period regardless of the system locale, set it explicitly:
Scanner scanner = new Scanner(System.in);
scanner.useLocale(Locale.US); // period as the decimal separator 5. Reading Lines: nextLine()
The next example uses the nextLine() method to read an entire line of input:
import java.util.Scanner;
public class ScannerExample3 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String s1, s2;
s1 = scanner.nextLine();
s2 = scanner.nextLine();
System.out.println(s1 + s2);
}
} Frequently Asked Questions
Why does nextLine() read an empty string after nextInt()?
Because nextInt() reads only the number but leaves the newline character from your Enter key in the buffer. The next nextLine() call immediately hits that newline and returns an empty string. To work around this, add an extra "throwaway" nextLine() after nextInt() to consume the leftover newline.
Why doesn't nextDouble() read a number with a period?
The nextDouble() method uses the decimal separator defined by the system's locale. In some locales the separator is a comma rather than a period, so entering 3.14 may throw an InputMismatchException. To make Scanner always expect a period, set the locale explicitly using Locale.US.
What's the difference between next() and nextLine()?
The next() method reads only a single word — up to the first space or line break. The nextLine() method reads the entire line, including spaces, until you press Enter. For example, for the input "John Smith", next() returns only "John", while nextLine() returns "John Smith".
Why use hasNextInt() before nextInt()?
The hasNextInt() method checks whether an integer can be read from the input stream and returns true or false. If you call nextInt() directly and the user enters something that isn't a number, the program crashes with an InputMismatchException. Checking with hasNextInt() lets you handle invalid input without crashing.
Comments