Scanner
The Purpose of Scanner
Programs often need to deal with raw input from files, System.in, or other sources. Many operations will require that the input be converted into a more code-friendly form than a giant block of text. For example, to do math on a list of integers, the input will need to be converted from one block of text into a collection of Java integers. The Scanner class is very useful for performing such conversions. The Scanner can deal with any input source in the same manner, which makes it easy to swap input sources without changing much code.
What Scanner does
Scanner breaks down raw input into "tokens" and can convert tokens into their proper Java data type. By default, tokens are space-separated Strings, but Scanner lets you change the token-splitting pattern. The next() method of Scanner will return the next token of input as a String. The Scanner keeps track of where it's up to in a given input, so every time that you call a next
method, it will return the next piece of input and move forward in the input.
Scanner constructors
Scanner has many different constructors for taking in input from many different sources. Anything that implements the Readable interface can be passed to Scanner to scan. Scanner can even take in a String as input, though this isn't so common, since String can usually handle itself fine on its own. These are the two most common Scanner constructors:
InputStream Constructor
public Scanner(InputStream source)
This Scanner takes in an InputStream as input, most commonly System.in. This is used to read from the Standard input such as the terminal or command-line.
Scanner in = new Scanner(System.in);
File Constructor
public Scanner(File source)
throws FileNotFoundException
This constructor takes in a File Object as input, and is used to read from actual files. Here is some example code (hover over each line for more info):
public static void main(String[] args) throws FileNotFoundException { File f = new File("sample"); Scanner scan = new Scanner(f); System.out.println( scan.next() ); }
(One could also use a BufferedReader and pass that into the Scanner instead of the file Object itself.)
Since the code is accessing a file, it throws a FileNotFoundException if the File isn't found, as seen in the method header above. One could also use a Try Catch block to Try to find the File, and Catch the Exception if it isn't found.
Method Overview
Many of the methods in Scanner have similar names, with the general form of hasNextThing()
and nextThing()
. For example, there's hasNextInt() and nextInt(). The "hasNextThing" methods are used to check if the next token of text input matches the format of type "Thing". For example, hasNextInt()
tells you if the next token of input can be interpreted as an integer. The "nextThing" methods read the next token and convert it to type "Thing". For example, nextInt()
reads the next token and converts it to an int
to return. If the next token cannot be converted to an int
, nextInt()
will throw an error.
input | code | returns |
---|---|---|
42 | hasNextInt() |
true |
hello | hasNextInt() |
false |
42 | nextInt() |
42 (as an int) |
hello | nextInt() |
Error! (InputMismatchException) |
The hasNextThing methods are usually used together with the nextThing methods to make sure the next Token is the right type. For example, given a Scanner in
, you can use an if
statement to get number input:
if( in.hasNextInt() ){
int num = in.nextInt();
//...
}
...or you can use a while
statement, such as this example which scans in words of input:
ArrayList<String> wordList = new ArrayList<String>();
while( in.hasNext() ){
String word = in.next();
wordList.add(word);
}
The above code adds each token of input as a word to the ArrayList wordList
. It only gets the next input while
there still is input, so it won't cause an error by calling in.next()
when there's nothing left.
Specific Methods
As mentioned, the hasNext methods check if the next token match a certain pattern, and the next method gets the next token and converts it to a specific type. The table below summarizes the common next/hasNext methods.
hasNext method - returns true if... | next Method - returns the _ from the input source. | Example code | Input | Print `value` (unless exception first) |
---|---|---|---|---|
boolean hasNext( ) ..another token of any type is available to be read. |
String next( ) ..next token of any type |
String value = scan.next(); |
The quick brown fox 23 |
The 23 |
boolean hasNextBoolean( ) ..a boolean value is available to be read. |
boolean nextBoolean( ) next token as a boolean value. |
boolean value = scan.nextBoolean( ); |
true 1 |
true InputMismatchException |
boolean hasNextDouble( ) ..a double value is available to be read. |
double nextDouble( ) next token as a double value |
double value = scan.nextDouble(); |
3 5 1.234 hello 1 |
3.0 1.234 InputMismatchException |
boolean hasNextFloat( ) ..a float value is available to be read. |
float nextFloat( ) next token as a float value |
float value = scan.nextFloat(); |
3 1.234 2/3 |
3.0 1.234 InputMismatchException |
boolean hasNextInt( ) ..an int value is available to be read. |
int nextInt( ) next token as an int value |
int value = scan.nextInt(); |
3 1.23 1234567890123456789 |
3 InputMismatchException InputMismatchException |
boolean hasNextLong( ) ..a long value is available to be read. |
long nextLong( ) next token as a long value. |
long value = scan.nextLong(); |
3 1.23 1234567890123456789 |
3 InputMismatchException 1234567890123456789 |
boolean hasNextLine( ) ..a line of input is available. |
String nextLine( ) next line of input as a string |
String value = scan.nextLine(); |
The quick brown fox {empty line} |
The quick brown fox {empty String} |
More Methods
There are also the next(Pattern pattern) and hasNext(Pattern pattern) methods to look for a specific regex Pattern. If you want to split all of the input by a custom pattern, you can use the useDelimiter(String pattern) method to specify what Strings (or Patterns) should be used to split up the input. For example, let's say you had a list of comma-separated words you wanted to scan.
one,two,three
If you set the delimiter to ,
(instead of the default whitespace), the Scanner will tokenize the input by its commas and let you access what's between:
Scanner scan = new Scanner(System.in);
scan.useDelimiter(",");
String word1 = scan.next();
String word2 = scan.next();
System.out.println(word1 +" "+ word2);
The above code will print
one two
Avoid Errors
Except when given very precise input (such as in programming challenges), you usually need to use if(hasNextThing) or while(hasNextThing) before actually getting the next token of input.
Be careful when using nextLine() after another method such as nextInt(). Even after nextInt takes a number on a line, the Scanner still hasn't gone to the next line. This means the first nextLine call will just return an empty String. For example, if given the following input:
1 hello world
Scanner scan = new Scanner(System.in);
int num = scan.nextInt();
String word1 = scan.nextLine();
String word2 = scan.nextLine();
System.out.println("word1: " + word1);
System.out.println("word2: " + word2);
word1
will be set to an empty String, and word2
will be set to hello, so the code will output:
word1: word2: hello
Challenge
This challenge below involves 3 simple parts. Each challenge is basic, but it will let you practice using Scanner.
- The first line of input contains an integer
n
. Following that aren
lines, each containing two integers. Print the sum of each integer pair. - After the pairs of number, there will be lists of numbers in the following format: The first line contains a number
m
.m
cases follow, with each case consisting of two lines:- A number
t
t
numbers on one line.
Return the sum of thet
numbers.
- A number
- The next line of input will contain a number
p
.p
lines follow, with each line containing a single word. Print "Hi word!" for each word.
The code is started below, but you need to fill-in the loop bodies.
Challenge
Can you use a Scanner to solve this 3-in-1-challenge?
Please sign in or sign up to submit answers.
Alternatively, you can try out Learneroo before signing up.
Comments
Victoria Holland
Feb 11, 10:13 AMI'm having trouble with this exercise - I get the correct output which is highlighted in green but the final line where it says "All Your Output" is highlighted in red. I'm assuming the problem is with the 3rd part - my code for that is as follows:
n = in.nextInt();
Learneroo
Feb 11, 10:23 AM@Victoria, you need to print it with an exclamation point at the end.
Gaston
Sep 21, 2:20 PMPlease give the answer, as i cannot find out what ive been doing wrong
Learneroo
Sep 21, 2:27 PMOK, here it is.
Gaston
Sep 21, 3:14 PMmy codegot it