Algol 68 files
last modified November 13, 2026
A FILE value is a channel to a file on disk, a terminal, or a
printer. A program opens a name with a channel that says whether it reads or
writes, transputs values through the file, and closes it when it is done. This
article describes opening, writing, reading, and closing files, reading every
line of a file, and writing numbers and formatted reports that a later run can
read back.
Writing a file
open(f, name, stand out channel) connects the variable
f to the file called name for output, and creates the
file if it does not exist. put and putf then write
through the file, and close releases it.
BEGIN
STRING name = "notes.txt";
FILE f;
open(f, name, stand out channel);
put(f, ("first line", newline));
put(f, ("second line", newline));
close(f);
print(("wrote two lines to ", name, newline))
END
The FILE variable needs no initial value; open fills
it in. Each put writes a row to the file, and the
newline in the row separates the two lines. After
close the file holds the text and the program reports the name it
used.
$ a68g writefile.a68 wrote two lines to notes.txt
Reading a file back
The same name is opened with stand in channel for reading, and
then get takes one line at a time. The string receives the
characters without the newline, which the second item of the row consumes.
BEGIN
STRING name = "notes.txt";
FILE f;
open(f, name, stand out channel);
put(f, ("alpha", newline));
put(f, ("beta", newline));
close(f);
open(f, name, stand in channel);
STRING line;
get(f, (line, newline));
print(("1: ", line, newline));
get(f, (line, newline));
print(("2: ", line, newline));
close(f)
END
The program writes the file first so that the example is complete, then opens
it for reading and takes the two lines. The text is the same as the text that
was written, because get of a string keeps every character up to
the newline. The final close releases the file.
$ a68g readfile.a68 1: alpha 2: beta
Every line of a file
A file of unknown length is read with the handler for the logical end of the
file. The handler sets a flag, and the loop stops when the flag becomes true,
which is the same pattern that the reading input article uses for
stand in.
BEGIN
STRING name = "notes.txt";
FILE f;
open(f, name, stand out channel);
put(f, ("alpha", newline));
put(f, ("beta", newline));
put(f, ("gamma", newline));
close(f);
open(f, name, stand in channel);
STRING line;
INT count := 0;
BOOL done := FALSE;
on logical file end(f, (REF FILE file) BOOL: done := TRUE);
WHILE NOT done DO
get(f, (line, newline));
IF NOT done THEN
count +:= 1;
print((whole(count, 0), ": ", line, newline))
FI
OD;
close(f)
END
The handler is installed on the file variable, so it applies to the reads that follow. The read that reaches the end of the file still returns, and the guard prevents the empty result from being printed. The loop numbers the three lines as it prints them, and the count is the number of lines in the file.
$ a68g alllines.a68 1: alpha 2: beta 3: gamma
Numbers in a file
A file holds characters, not values, so a program that stores numbers first
turns them into text. putf with a g frame writes a
number without padding, and get with an INT variable
converts it back.
BEGIN
STRING name = "values.txt";
FILE f;
open(f, name, stand out channel);
[]INT values = (10, 20, 30, 40);
FOR i TO UPB values DO
putf(f, ($g(0)$, values[i]));
put(f, (newline))
OD;
close(f);
open(f, name, stand in channel);
INT n, total := 0;
BOOL done := FALSE;
on logical file end(f, (REF FILE file) BOOL: done := TRUE);
WHILE NOT done DO
get(f, (n, newline));
IF NOT done THEN total +:= n FI
OD;
close(f);
print(("total ", whole(total, 0), newline))
END
Each number is written as its decimal digits followed by a newline, so a line
of the file can be read back as an integer. The second loop converts every
line into n and adds it to the total, which is 100. A number that
does not fit the mode of the variable would raise a value error, which
on value error can handle.
$ a68g numbers.a68 total 100
Opening for output clears the file
open with stand out channel always starts at the
beginning of an empty file. Opening an existing name again therefore discards
what it held, and the new content is the only content that remains.
BEGIN
STRING name = "log.txt";
FILE f;
open(f, name, stand out channel);
put(f, ("first run", newline));
close(f);
open(f, name, stand out channel);
put(f, ("second run", newline));
close(f);
open(f, name, stand in channel);
STRING line;
get(f, (line, newline));
print(("the file now holds: ", line, newline));
close(f)
END
The second write does not append to the first; it replaces it, so the file holds one line. A program that wants to keep the old content has to read the file before it opens it for output, or write to a different name. The implementation has no channel that appends to an existing file.
$ a68g truncate.a68 the file now holds: second run
A formatted report
putf writes a formatted row to a file, so a report can be built
from frames just as it is on the terminal. Reading the report back as lines
shows the text that the format produced.
BEGIN
STRING name = "report.txt";
FILE f;
open(f, name, stand out channel);
[]INT values = (7, 42, 1234);
FOR i TO UPB values DO
putf(f, ($g(-6)$, values[i]));
putf(f, ($" square "g(-8)$, values[i] * values[i]));
put(f, (newline))
OD;
close(f);
open(f, name, stand in channel);
STRING line;
BOOL done := FALSE;
on logical file end(f, (REF FILE file) BOOL: done := TRUE);
WHILE NOT done DO
get(f, (line, newline));
IF NOT done THEN print(("| ", line, newline)) FI
OD;
close(f)
END
Each line of the report holds a number in a field of six characters and its square in a field of eight, so the columns of the file line up. The reading part prints every line with a bar in front of it, which shows that the spaces of the fields are part of the file. A report built this way can be printed or looked at with any text tool.
$ a68g report.a68 | 7 square 49 | 42 square 1764 | 1234 square 1522756
The standard files
Every program has three files open before its first statement:
stand out, stand in, and stand error.
print and printf write to stand out,
the reading procedures take values from stand in, and the
interpreter writes its diagnostics to stand error. A program may
pass any of them to put, putf, get, or
read, which is why the same procedures serve both the terminal
and a file of the program's own.
A file value carries more than the name: the channel decides whether the file is read or written, and the position of the next character moves with every transput. That is why a file must be closed and opened again with a different channel before it can be read after it has been written.
Next steps
The reading input article covers the same
reading procedures on stand in, and the
formatted transput article explains
the frames that putf uses. The
command-line arguments article
shows how a script takes a file name from its arguments, and
strings explains the text that a file holds.
Source
Revised Report on the Algorithmic Language Algol 68
In this article we have opened files for writing and reading, written lines and numbers, read them back, walked every line of a file with a handler for its end, seen that opening for output clears a file, and written a formatted report. The command-line arguments article continues with the values that a script receives from its caller.
Author
List all Algol 68 tutorials.