Scanner


Collapse Content

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.

  1. The first line of input contains an integer n. Following that are n lines, each containing two integers. Print the sum of each integer pair.
  2. 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 the t numbers.
  3. 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

  • I'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();

    cont...
  • @Victoria, you need to print it with an exclamation point at the end.

  • Please give the answer, as i cannot find out what ive been doing wrong

All Node Comments
Contact Us
Sign in or email us at [email protected]