A-Level Computer Science / Unit 10: Organising Data in Programs

10.3.2 Reading Multi-line Text Files

πŸ”’ Lesson slides are available to signed-in users. Sign in

10.3.2 Reading Multi-line Text Files

A text file may contain no lines, one line or many lines. A program normally reads one complete line at a time into a string variable. To process the whole file safely, it checks whether the end has been reached before attempting the next read.

By the end of this section, you should be able to:

  • Open an existing text file in READ mode.
  • Use READFILE to place one line into a string variable.
  • Explain how the current read position advances through a file.
  • Interpret the Boolean result returned by EOF().
  • Use WHILE NOT EOF(filename) to process every line safely.
  • Trace the behaviour of a reading loop for multi-line, single-line and empty files.
  • Adapt the basic loop to count, search for or temporarily store file lines.
Scope of this page: creating and appending files were covered in 10.3.1. This page concentrates on reading existing text files.

Reading One Line

Consider a delivery-status file containing one update per line:

DispatchNotes.txt
Van 14 | loading
Bike 08 | departed
Locker 21 | delayed
Drone 03 | inspection

The file must be opened for reading before READFILE is used. One call to READFILE copies the next unread line into a variable.

DECLARE CurrentLine : STRING

OPENFILE "DispatchNotes.txt" FOR READ
READFILE "DispatchNotes.txt", CurrentLine
OUTPUT CurrentLine
CLOSEFILE "DispatchNotes.txt"

This code outputs only the first line: "Van 14 | loading".

Statement Purpose
OPENFILE "DispatchNotes.txt" FOR READ Opens the existing file so its contents can be read.
READFILE "DispatchNotes.txt", CurrentLine Copies the next unread line into CurrentLine.
CLOSEFILE "DispatchNotes.txt" Finishes access to the file.
Common mistake: A single READFILE statement does not read an entire multi-line file. It reads only the next line.

The Current Read Position

An open file has a conceptual read position. When the file is first opened, the position is before the first line. Each successful READFILE operation advances it to the following line.

After... Value copied into CurrentLine Next unread line
Opening the file None Line 1
First READFILE "Van 14 | loading" Line 2
Second READFILE "Bike 08 | departed" Line 3
Fourth READFILE "Drone 03 | inspection" No unread lines remain
Current read position: the point in an open file from which the next line will be read.
When tracing file pseudocode, record both the value of the string variable and which line will be read next.

Testing for End of File

A program cannot safely keep calling READFILE forever. It needs a way to detect that no unread lines remain.

EOF(filename): a Boolean function that tests whether the end of the specified file has been reached.
File state EOF(filename) NOT EOF(filename)
At least one unread line remains FALSE TRUE
No unread lines remain TRUE FALSE
Common misconception: EOF() is not TRUE while there is data available. It becomes TRUE when the reading position has reached the end.
Read WHILE NOT EOF(filename) as: β€œwhile the file has not finished”.

Reading Every Line

A pre-condition loop checks for unread data before each call to READFILE. The basic whole-file pattern is:

DECLARE CurrentLine : STRING

OPENFILE "DispatchNotes.txt" FOR READ

WHILE NOT EOF("DispatchNotes.txt") DO
    READFILE "DispatchNotes.txt", CurrentLine
    OUTPUT CurrentLine
ENDWHILE

CLOSEFILE "DispatchNotes.txt"

Structure of the algorithm

Stage What happens
Open The file is opened once in READ mode.
Test EOF() checks whether another line is available.
Read The next line is copied into CurrentLine.
Process The program uses the line; here it outputs it.
Repeat The loop returns to the EOF test.
Close The file is closed once no unread lines remain.
Keep READFILE inside the loop. Otherwise the program may repeatedly process the same stored value without advancing through the file.

Worked Trace: Four-line File

The following trace shows the loop reading DispatchNotes.txt.

Loop test EOF() Line read CurrentLine Action
1 FALSE 1 "Van 14 | loading" Output line 1
2 FALSE 2 "Bike 08 | departed" Output line 2
3 FALSE 3 "Locker 21 | delayed" Output line 3
4 FALSE 4 "Drone 03 | inspection" Output line 4
5 TRUE None Unchanged Leave the loop
The loop body executes four times, but the EOF condition is tested five times: once before each line and once more after the final line.
Do not add an extra READFILE after the loop. The loop has already consumed every available line.

Why a WHILE Loop Handles an Empty File Safely

An empty file contains no data lines. Immediately after it is opened, EOF(filename) is TRUE.

OPENFILE "NoUpdates.txt" FOR READ

WHILE NOT EOF("NoUpdates.txt") DO
    READFILE "NoUpdates.txt", CurrentLine
    OUTPUT CurrentLine
ENDWHILE

CLOSEFILE "NoUpdates.txt"

Because NOT EOF("NoUpdates.txt") is FALSE at the first test, the loop body does not execute. No invalid read is attempted.

File Initial EOF() Loop-body executions
Empty file TRUE 0
One-line file FALSE 1
Four-line file FALSE 4
A pre-condition loop is a strong choice when the file may be empty because it tests before the first read.

Processing Each Line

Output is only one possible action. The statement after READFILE can count lines, compare the current line with a target, or perform another suitable operation.

Count the number of lines

DECLARE CurrentLine : STRING
DECLARE LineCount : INTEGER

LineCount ← 0

OPENFILE "DispatchNotes.txt" FOR READ

WHILE NOT EOF("DispatchNotes.txt") DO
    READFILE "DispatchNotes.txt", CurrentLine
    LineCount ← LineCount + 1
ENDWHILE

CLOSEFILE "DispatchNotes.txt"
OUTPUT LineCount

Find the first exact matching line

DECLARE CurrentLine : STRING
DECLARE WantedLine : STRING
DECLARE Found : BOOLEAN

WantedLine ← "Locker 21 | delayed"
Found ← FALSE

OPENFILE "DispatchNotes.txt" FOR READ

WHILE NOT EOF("DispatchNotes.txt") AND Found = FALSE DO
    READFILE "DispatchNotes.txt", CurrentLine

    IF CurrentLine = WantedLine
      THEN
        Found ← TRUE
    ENDIF
ENDWHILE

CLOSEFILE "DispatchNotes.txt"

IF Found = TRUE
  THEN
    OUTPUT "Matching line found"
  ELSE
    OUTPUT "Matching line not found"
ENDIF
Common mistake: The file should still be closed when the search stops early after finding a match.

Loading File Lines into an Array

A program may read persistent file data into an array so it can process the values during the current run. The array must have enough space for the lines being loaded.

DECLARE Notice : ARRAY[1:20] OF STRING
DECLARE Index : INTEGER
DECLARE LinesLoaded : INTEGER

Index ← 1

OPENFILE "Notices.txt" FOR READ

WHILE NOT EOF("Notices.txt") AND Index <= 20 DO
    READFILE "Notices.txt", Notice[Index]
    Index ← Index + 1
ENDWHILE

CLOSEFILE "Notices.txt"

LinesLoaded ← Index - 1
Condition Why it is needed
NOT EOF("Notices.txt") Stops when the file has no unread lines.
Index <= 20 Stops before the array's upper bound is exceeded.
If the file can contain more lines than the array can hold, the algorithm needs a capacity check. EOF alone does not prevent an out-of-range array access.

Interactive: Multi-line File Reader

Choose a multi-line, single-line or empty file. Step through the EOF test, read and processing stages while the widget tracks the read position and current string value.

DispatchNotes.txt
EOF
Current pseudocode stage
OPENFILE "DispatchNotes.txt" FOR READ
Stage Ready
EOF() β€”
Next line 1
Lines read 0
CurrentLine Not assigned
Program output
(no output yet)

Press Start / restart to open the file.

Common Mistakes and Misconceptions

  • Opening the file in WRITE or APPEND mode when it should be read.
  • Assuming one READFILE statement reads every line.
  • Using WHILE EOF(filename) instead of WHILE NOT EOF(filename).
  • Calling READFILE after EOF() has become TRUE.
  • Placing READFILE outside the loop and repeatedly processing the same variable value.
  • Forgetting that each read replaces the previous value stored in the string variable.
  • Leaving the file open after a whole-file loop or an early search result.
  • Assuming an empty file will execute the loop once.
  • Loading lines into an array without checking the array's upper bound.

Practice

Task 1: Read and output every line

Write pseudocode that opens "RouteAlerts.txt", outputs every line and then closes the file.

Task 2: Trace the loop

RoomStatus.txt
Lab 2 | open
Studio 4 | booked
Workshop 1 | closed
  1. List the successive values assigned to CurrentLine.
  2. How many times is READFILE executed?
  3. How many times is the EOF condition tested?
  4. What is the value of EOF() at the final test?

Task 3: Count lines

Adapt a whole-file reading loop so that it outputs the number of lines in "Bookings.txt". Use an integer called BookingCount.

Task 4: Find the errors

OPENFILE "Messages.txt" FOR READ
READFILE "Messages.txt", Message

WHILE EOF("Messages.txt") DO
    OUTPUT Message
ENDWHILE
  1. Identify at least three problems.
  2. Rewrite the complete algorithm correctly.

Task 5: Load an array safely

TaskName is declared as ARRAY[3:14] OF STRING. Write pseudocode that reads as many lines as possible from "Tasks.txt" without exceeding the array bounds.

Review

Question Strong answer should include
What does READFILE do? It copies the next unread line into a variable and advances the read position.
What does EOF() return while unread data remain? FALSE.
Why use WHILE NOT EOF()? It checks that another line exists before attempting each read.
How does an empty file behave? The first EOF test is TRUE, so the loop body executes zero times.
Where should the file be closed? After the loop, or after any early termination from processing.
What extra condition is needed when loading a fixed-size array? A check that the next index is not above the array's upper bound.
Final exam tip: Check the full sequence: open for READ, test NOT EOF(), read one line, process it, repeat, then close the file.