Room 10 of 15 · about 25 minutes

What a line read returns

Room 9 named the two kinds of read. This room takes the line kind apart, because a file with one record per line is read with line reads, and what a line read hands back is not the whole line as it sits in the file.

Tasks checked0 of 3 XP earned on this path0

What this room checks you can do

Student can predict what sc.nextLine() returns given the file's current cursor position, identify that the line terminator is consumed but not part of the return value, and recognize the three cases: non-empty line, empty line, partial last line: by what each returns.

Notes

What nextLine() actually reads

Scanner.nextLine() reads characters from the current cursor position up to and including the next line terminator, then returns everything before the terminator as a String. The terminator is consumed but not returned. The cursor lands one character past it.

//  Suppose the file contains:  Alice\nBob\nCarol\n
final Scanner sc = new Scanner(new File("names.txt"));

String first  = sc.nextLine();   //  "Alice" : cursor now between \n and 'B'
String second = sc.nextLine();   //  "Bob"
String third  = sc.nextLine();   //  "Carol"

Three properties of nextLine() worth committing to memory:

1. The newline is consumed but not returned. The returned String has no \n at the end. Code that appends "\n" for printing is doing the right thing; code that strips a trailing newline from the return is acting on a newline that is not there. 2. Empty lines return empty strings. Two consecutive \n characters mean "an empty line." nextLine() returns "" and the cursor moves past the second newline. Code that filters out blank lines must compare against "" (or use String.isBlank() for whitespace-only lines). 3. The cursor's position before the call decides what is returned. If a previous nextInt() or next() left the cursor mid-line, nextLine() reads from that mid-line position to the next newline. The trap that follows a token-mode read with nextLine covers this in detail, and it is the single most common Scanner bug in CS1.

Line terminator details

Java's Scanner recognizes the three common line endings: \n (Unix), \r\n (Windows), \r alone (old Mac). All three are consumed and produce the same return. A file edited on Windows and read on Linux behaves the same way; the Scanner documentation calls this "line terminator portability."

The trade-off: the String returned never carries the original line ending. A program that needs to preserve "this file was Windows-style" must read the file with Files.readString or similar instead.

When the last line lacks a terminator

Some text files end without a final \n (Windows Notepad sometimes does this; so do programs that fail mid-write). The behavior is:

  • nextLine() reads the partial last line and returns it.
  • The cursor lands at end-of-stream.
  • hasNextLine() returns false after the read.

The lack of a trailing newline does not lose data. The last line is still returned by the last nextLine() call.

In other languages

  • Python: for line in f: includes the trailing \n; line.rstrip() is the typical fix. Java strips it for you.
  • C: fgets(buf, sizeof buf, fp) includes the \n if the buffer was long enough; strcspn or manual trim removes it.
  • JavaScript (Node): readline.Interface .on('line', ...) strips the line terminator like Java does.

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

    "Alice", "Bob", then NoSuchElementException (no more lines).

  2. trace
    Show the answer

    "Hello", "", "World".

  3. write
    Show the answer

    while (sc.hasNextLine()) { String line = sc.nextLine(); if (!line.isBlank()) count++; }.

Self check

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

Identify what sc.nextLine() returns immediately after sc.nextLine() on the last line of a file.

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. Given the file Final\n versus the file Final (no terminating newline), predict the difference in nextLine() behavior.trace
    Show the answer

    both return "Final"; the difference is the position of the cursor after the call (just past the \n vs at EOF).

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 predict what sc.nextLine() returns given the file's current cursor position, identify that the line terminator is consumed but not part of the return value, and recognize the three cases: non-empty line, empty line, partial last line: by what each returns.

How this room finishes

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