Reading input in Fortran
last modified November 14, 2026
A program that only prints results is a demonstration; a program that reads
data is a tool. Fortran reads from the standard input, the stream of
characters that comes from the keyboard or from a pipe, a channel that feeds
another program's output into this one, and it writes to the
standard output, the screen or a redirected file. The unit
* in a read statement means the standard input, and
the format * means list-directed input, where the
compiler splits each line into fields and converts them to the types of the
variables. This article shows how to read numbers, whole lines and tables,
how to notice the end of the input with iostat, and how to keep
a loop going until a special value arrives.
Reading numbers
The statement read (*, *) a, b takes two integers from the next
line of input. List-directed input does not require fixed columns: the values
may be separated by one or more blanks or by commas, and the compiler skips
the blanks before each value. A prompt is just a write without a
line break, produced by advance='no', which leaves the record
open so that the answer appears after the question on the same line.
program r1
implicit none
integer :: a, b
write (*, '(a)', advance='no') 'Enter two integers: '
read (*, *) a, b
write (*, '(/, a, i0, a, i0)') 'sum = ', a + b, ', product = ', a * b
end program r1
The transcript below feeds the line 3 4 into the program through
a pipe, which is the same thing the program would see from a keyboard. The
prompt is printed without a newline, the read consumes the two numbers, and
the result starts on the next line because the format begins with a slash.
The slash has to be there: without it the answer would continue on the prompt
line, mixing with the question.
$ gfortran r1.f90 -o r1 $ printf '3 4\n' | ./r1 Enter two integers: sum = 7, product = 12
Reading a whole line
When the input is text rather than numbers, reading it as a number is
impossible and reading it field by field is fragile. The reliable approach is
to read the whole line into a character variable with the format
'(a)', which copies the rest of the record without trying to
interpret it. The line can then be inspected with the string functions, or
parsed with an internal read, where the character variable itself
supplies the fields, as described in the
internal files article.
program r2
implicit none
character(len=80) :: line
character(len=20) :: name
integer :: age, ios
write (*, '(a)', advance='no') 'name and age: '
read (*, '(a)') line
read (line, *, iostat=ios) name, age
if (ios == 0) then
write (*, '(/, a, a, i0, a)') trim(name), ' is ', age, ' years old'
else
write (*, '(/, a)') 'could not parse the line'
end if
end program r2
The line Alice 30 is read whole, then the internal read splits it
at the blank and converts the second field to an integer. In list-directed
character input a blank ends the field, so Alice is stored and
the rest of the line is left for the integer. With nonsense the
second read fails, the status is not zero, and the program prints its own
message instead of stopping with a runtime error.
$ gfortran r2.f90 -o r2 $ printf 'Alice 30\n' | ./r2 name and age: Alice is 30 years old
Reading until the end of the input
Real input has no known length, so a loop must stop when the data runs out.
The iostat argument of read answers that question:
zero means a value arrived, a negative value means the end of the input was
reached, and a positive value means the text did not match the variables. A
counted loop cannot do this job, since the number of values is exactly what is
unknown, so the loop repeats until the status becomes non-zero.
program r3
implicit none
integer :: ios, count
real :: x, total
count = 0
total = 0.0
do
read (*, *, iostat=ios) x
if (ios /= 0) exit
count = count + 1
total = total + x
end do
write (*, '(a, i0)') 'values: ', count
write (*, '(a, f8.2)') 'total: ', total
if (count > 0) write (*, '(a, f8.2)') 'mean: ', total / count
end program r3
The input below has three numbers and one blank line. List-directed input
skips the blank line, so three values are counted and the total is 8. The loop
ends when the next read finds no more characters, which is the end-of-file
condition with a negative status. The final if protects the mean
against an empty input, where dividing by the count would produce a division
by zero.
$ gfortran r3.f90 -o r3 $ printf '1.5\n2.5\n\n4\n' | ./r3 values: 3 total: 8.00 mean: 2.67
Prompts and a sentinel value
A sentinel is a value that has no meaning as data and marks the end of it: zero for a sum of positive numbers, minus one for a list of counts, an empty line for a list of names. The loop reads one value, tests it, and leaves before using it. Printing the value that was read makes the interaction with the program visible, which is useful while the input is being typed and harmless when it is piped from a file.
program r4
implicit none
integer :: n, total
total = 0
do
write (*, '(a)', advance='no') 'next number (0 to stop): '
read (*, *) n
write (*, '(a, i0)') ' read ', n
if (n == 0) exit
total = total + n
end do
write (*, '(a, i0)') 'total: ', total
end program r4
Each pass prints the prompt without a newline, reads a number, and prints what it read, so every exchange occupies one line of the transcript. The numbers 4 and 5 are added and the final 0 stops the loop before it can change the total. This loop assumes that the input is well formed; if the read fails, the program stops with an error, which is acceptable for a small interactive tool but not for data from a file.
$ gfortran r4.f90 -o r4 $ printf '4\n5\n0\n' | ./r4 next number (0 to stop): read 4 next number (0 to stop): read 5 next number (0 to stop): read 0 total: 9
Counting lines and words
Reading a line at a time and testing its status is the standard way to process
a text file. The program below counts the lines and the words, where a word is
a run of non-blank characters, as in the
string processing article. The
format '(a)' copies each record into the buffer, and
len_trim gives the part that is not padding.
program r5
implicit none
character(len=120) :: line
logical :: prev_blank
integer :: ios, lines, words, i
lines = 0
words = 0
do
read (*, '(a)', iostat=ios) line
if (ios /= 0) exit
lines = lines + 1
prev_blank = .true.
do i = 1, len_trim(line)
if (line(i:i) == ' ') then
prev_blank = .true.
else
if (prev_blank) words = words + 1
prev_blank = .false.
end if
end do
end do
write (*, '(a, i0)') 'lines: ', lines
write (*, '(a, i0)') 'words: ', words
end program r5
The input has three lines, the last of them empty, and six words in total. A
word is counted when a non-blank character follows a blank or starts the line,
which is why prev_blank begins as true. The empty line counts as
a line but adds no words. Because the loop reads whole records, the program
does not care how many fields a line holds or what types they are.
$ gfortran r5.f90 -o r5 $ printf 'Fortran is fun\na compiled language\n\n' | ./r5 lines: 3 words: 6
Validating each line
Data from a file often contains a broken line, and a program that stops at the first one is not much use. The pattern is to read the line as text, try to parse it with an internal read, and use the status to decide between a result and a message. Each line is handled on its own, so one bad record does not prevent the rest from being processed, and the program can report exactly what it skipped.
program r6
implicit none
character(len=80) :: line
character(len=20) :: name
real :: s1, s2
integer :: ios
do
read (*, '(a)', iostat=ios) line
if (ios /= 0) exit
if (len_trim(line) == 0) cycle
read (line, *, iostat=ios) name, s1, s2
if (ios /= 0) then
write (*, '(a, a)') 'skipped: ', trim(line)
else
write (*, '(a, a, a, f5.1)') trim(name), ': ', 'average ', (s1 + s2) / 2.0
end if
end do
end program r6
The first two lines hold a name and two scores and produce an average. The
third line is text that cannot be converted, so the program prints it with a
skipped: prefix and continues. Blank lines are ignored by the
cycle statement, which jumps to the next iteration. Reading the
record into line first is what makes the recovery possible: the
bad text is still available for the message, because the failed internal read
left the original characters intact.
$ gfortran r6.f90 -o r6 $ printf 'Alice 80 90\nBob 70 60\nmalformed line\n' | ./r6 Alice: average 85.0 Bob: average 65.0 skipped: malformed line
Next steps
The formatted output article explains the formats used for the prompts and the results, and the internal files article covers the string-to-number conversion in detail. The string processing article shows how to split the lines further, and the files article replaces the standard input with a file opened by name.
Source
Fortran 2018 standard (J3/18-007r1)
Fortran-lang: learning resources
In this article we have read numbers and whole lines from the standard input,
detected the end of the data with iostat, stopped a loop on a
sentinel value, counted the lines and words of a text, and recovered from a
line that could not be parsed. The previous article,
Fortran formatted output, explains
the formats that shape what the program prints while it reads.
Author
List all Fortran tutorials.