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 ofnextInt();%sfornext(). Same trap with the trailing newline. - Python: no built-in token mode; the idiom is
line.split()to get a list of strings, thenint(...)per token to parse. - C++:
cin >> n;is the analog; same skip-whitespace, same trailing-newline issue.