An instance of the java.util.Scanner class is for reading from a source of textual input data. The most likely source of such data is the keyboard (System.in) or a text file (typically having a .txt extension). A Scanner can also be set up to read from a value of type String. Any class that uses a Scanner must include the appropriate import statement above the class heading:
When creating an instance of the Scanner class (i.e., a Scanner object), you must use the new operator and specify the source from which it is to read data. Examples:
Expression | Effect |
---|---|
new Scanner(System.in) | Creates a Scanner that can read from the keyboard |
new Scanner(new File("glorp.txt")) | Creates a Scanner that can read from the file named glorp.txt |
new Scanner("Chris Smith 4 8.2 7.6 8.5 9.0") | Creates a Scanner that can "read" from the specified String |
Typically, an expression such as shown in the table above will occur as the right-hand side of an assignment statement (possibly combined with a declaration), as in the familiar
Ann Gourdhead 1989-11-30 23.40 Jim 2000 17 engineer 2.7E-5 -15 |
You can think of a Scanner as having a cursor that keeps track of its position within the text. When first created, a Scanner's cursor is positioned, as you would expect, at the beginning of the input text. A Scanner has several functional methods —each with a name having next as a prefix— that return the "next" token and cause the cursor to advance just beyond that token. Which of these methods you would call (to read the next token) depends upon what type of value you expect the next token to represent: int, double, boolean, String, etc.
Letting input be of type Scanner, here are examples of invocations of methods in the java.util.Scanner class:
method Invocation |
Return Type | Value Returned | Side Effect | Possible Exceptions |
---|---|---|---|---|
input.next() | String | the next input token | the cursor has advanced past the returned token | java.util.NoSuchElementException |
input.hasNext() | boolean | true if there is a next input token, false otherwise | none | none | input.nextInt() | int | the next input token, translated into a value of type int. Throws InputMismatchException if the next token is not of a form that can be translated into an integer. | the cursor has advanced past the returned token | java.util.NoSuchElementException java.util.InputMismatchException |
input.hasNextInt() | boolean | true if there is a next input token and it is of a form that can be translated into an integer, false otherwise | none | none |
input.nextDouble() | int | the next input token, translated into a value of type double. Throws InputMismatchException if the next token is not of a form that can be translated into a real number. | the cursor has advanced past the returned token | java.util.NoSuchElementException java.util.InputMismatchException |
input.hasNextDouble() | boolean | true if there is a next input token and it is of a form that can be translated into a real number, false otherwise | none | none |
input.nextLine() | String | the rest of the current line of input (up to a newline character) | the cursor has advanced to the beginning of the next line | java.util.NoSuchElementException |
input.hasNextLine() | boolean | true if there is more input data (even if it is all whitespace and therefore no tokens remain) | none | none |
Any token can be read as a String using next().
The methods that read in the "next token" (e.g., next(), nextInt(), etc.) do not respect line boundaries. That is, they treat an occurrence of the newline character just as though it were a space. Thus, a call to any of these methods will move the cursor forward, past the next token (which it will return), even if that token appears one or more lines below the cursor's position.
Ann Gourdhead 1989-11-30 23.40 Jim 2000 17 engineer 2.7E-5 -15 |
For a token to be readable via the nextDouble() method, it must be a sequence of characters that could serve as a double literal in a Java program. Among the tokens in this example, that includes all the ones that could serve as int literals, plus 23.40 and 2.7E-5. Attempting to read any other token using nextDouble() would result in an InputMismatchException being thrown.
If the cursor is positioned after the very last token in a source of input, an attempt to read the next token using any of nextXXX() methods results in a NoSuchElementException being thrown. Similarly, if the cursor has advanced beyond the end of the last line of input, calling nextLine() results in a NoSuchElementException being thrown.
The nextLine() method is a bit unique in that it doesn't read a token but rather all the characters up to the end of the current line (i.e., up to the next occurrence of a newline character), which may include zero or more tokens. The cursor advances to the beginning of the next line.
This behavior is a frequent source of confusion, because it seems natural to assume that if the last token on a line already has been read (e.g., using one of the nextXXX() methods that reads a single token), the cursor would have advanced to the beginning of the next line. But that is not how it works.
Elmo Wright Kansas City Chiefs |
You might think that execution of the code segment shown below and left would have the desired effect (where in refers to the Scanner):
String firstName = in.next(); String lastName = in.next(); String team = in.nextLine(); |
String firstName = in.next(); String lastName = in.next(); in.nextLine(); // advance to line containing team name String team = in.nextLine(); |
WRONG! | RIGHT! |
---|
But you would be wrong, because the second call to next() leaves the cursor at the position immediately following the 't' in "Wright", and not at the beginning of the next line. The call to nextLine(), therefore, will advance the token to the beginning of the second line, passing over the (zero or more) spaces and the newline character that follows that 't'. The String returned by that call will be the string composed of those (zero or more) spaces.
To get the desired effect, it is necessary to call nextLine() twice, the first time to advance the cursor to the second line and the second time to read the data on that line (i.e., the team name).