Room 11 of 15 · about 25 minutes

Reading a number and a word as tokens

Room 10 took the line read apart. This room does the same for the token read, which is what a line holding more than one value needs. It is also where you find out what happens when the text in the file does not fit the type you asked for.

Tasks checked0 of 3 XP earned on this path0

What this room checks you can do

Student can choose between next(), nextInt(), nextDouble() for reading from a Scanner based on the expected token type, predict the exception thrown when the token cannot be parsed (InputMismatchException), and recognize the cursor-position rule that produces the trailing-whitespace trap.

Notes

next() versus nextInt(): token mode

Scanner has two modes for reading input: line mode and token mode. Token-mode methods read a single whitespace-delimited token and return it. They are the right tool when the file's structure is "values separated by whitespace": spaces, tabs, newlines, any combination.

//  Suppose the file contains:  42 3.14 hello\n  7 2.71 world\n

final Scanner sc = new Scanner(new File("data.txt"));

int    a = sc.nextInt();      //  42
double b = sc.nextDouble();   //  3.14
String c = sc.next();         //  "hello"
int    d = sc.nextInt();      //  7

Three properties of the token-mode methods that distinguish them from nextLine():

1. Whitespace is the delimiter, not the data. Any run of spaces, tabs, and newlines between tokens is skipped automatically. The file 42\n\n\n3.14 reads as two tokens; 42 3.14 reads as two tokens; both behave identically. Reading the same two files with nextLine() would have produced very different output. 2. nextInt() returns the parsed int, not the string. The method parses the token as a base-10 integer. If the token cannot be parsed (e.g., "abc" or "3.14"), InputMismatchException is thrown. Same for nextDouble(), nextLong(), nextBoolean(). 3. **The cursor stops immediately after the last character of the token.** This is the same cursor-position rule that produces the nextInt-then-nextLine trap. After sc.nextInt() reads 42, the cursor sits between 2 and the next character: typically a space or newline that the next token-mode call will skip past but nextLine() would catch as an empty line.

next() reads a string token

sc.next() reads one whitespace-delimited token and returns it as a String, no parsing involved. It is the token-mode analog of nextLine() for line mode:

//  File: alice 30 bob 25 carol 19

while (sc.hasNext()) {
    String name = sc.next();      //  one name token
    int age = sc.nextInt();       //  one int token
    System.out.println(name + " is " + age);
}

Three token-mode reads (next, nextInt, next, nextInt, ...) walk through the alternating name age name age pattern without any line-terminator gymnastics.

The pairing rule

A file format is either line-oriented (one record per line; the record may have internal structure) or token-oriented (whitespace separates every value). Reading line-oriented data with token-mode methods works only when the within-line structure is single-token-per-line: in which case the file is also token-oriented, and either mode is fine. Reading truly line-oriented data (e.g., the line itself is a CSV row that needs to be parsed) requires nextLine() followed by String.split(",").

CSCD 210 Lab 11 (Typed File Stats) uses the token mode for the value lines (every line is one value) and nextLine() for the type tag (which is one whole line by itself, and is read first so no whitespace mixing can occur).

hasNextInt() and friends

The has-test versions exist for each typed read:

while (sc.hasNextInt()) {
    int v = sc.nextInt();
    // ...
}

hasNextInt() looks at the next token without consuming it and returns true only if the token parses as an int. This is the pattern for "read integers until we see something that is not one." Reading until the end of the file covers the loop shapes, and this is the typed variant.

In other languages

  • C: fscanf("%d", &n) is the analog of nextInt(); %s for next(). Same trap with the trailing newline.
  • Python: no built-in token mode; the idiom is line.split() to get a list of strings, then int(...) per token to parse.
  • C++: cin >> n; is the analog; same skip-whitespace, same trailing-newline issue.

What this room assumes you already have

Tasks

Do each one, then check the box. Checking a box is you saying you did it. You can uncheck a box if you check it by accident.

  1. trace
    Show the answer

    42, "hello", 3.14, "world".

  2. trace
    Show the answer

    InputMismatchException on the second nextInt() (the token "hello" is not an integer).

  3. write
    Show the answer

    String name = sc.next(); int age = sc.nextInt();.

Self check

Type what you think the answer is. Getting it wrong costs nothing and you can try as many times as you want.

Given the file 42 \n (leading and trailing spaces) and int a = sc.nextInt();, predict the value.

Practice, untimed

Open this whenever you want, before the tasks or after them. Nothing in this section is recorded and nothing here is timed.

  1. Write a loop that reads integers from a Scanner until the next token is not an integer.write
    Show the answer

    while (sc.hasNextInt()) { int v = sc.nextInt(); ... }.

Optional challenge

This one is optional. Do what the room says you can do, without opening any answers, then read the two traps below and check your work against them. Each trap is copied from the notes for this room.

Student can choose between next(), nextInt(), nextDouble() for reading from a Scanner based on the expected token type, predict the exception thrown when the token cannot be parsed (InputMismatchException), and recognize the cursor-position rule that produces the trailing-whitespace trap.

How this room finishes

This room is done when all three tasks are checked and the self check is answered.