Fortran namelists
last modified November 14, 2026
A program with many settings needs a way to read them that is more forgiving
than a fixed-column file. A namelist is a named group of variables
that can be written and read as a unit, in a format that names each value:
nx = 200 rather than a number in column five. The runtime matches
the names in the input with the variables of the group, so the order does not
matter, values may be missing, and extra whitespace is ignored. This article
shows how to declare a namelist, write it to a configuration file, read it back
with defaults for the values that are absent, use namelists without any file at
all, and recognise the two ways such a read can fail.
Declaring and writing a namelist
The declaration namelist /config/ nx, ny, dt, verbose, title does
two things at once: it gives the group the name config and lists
the variables that belong to it. The group is then used through the
nml= specifier of read and write, in the
same place where a format usually stands. The program below fills the
variables, writes the group to a file, and the file on disk shows the format:
an opening &config, one assignment per line, and a closing
slash.
program m1
implicit none
integer :: nx, ny
real :: dt
logical :: verbose
character(len=20) :: title
namelist /config/ nx, ny, dt, verbose, title
integer :: u
nx = 100
ny = 50
dt = 0.01
verbose = .true.
title = 'run one'
open (newunit=u, file='config.nml', status='replace')
write (u, nml=config)
close (u)
print *, 'wrote config.nml'
end program m1
The output is valid input: the same file can be read back by any program that
declares a group with the same names and compatible types. The name of the
group appears in upper case in this runtime, and the values are aligned with
blanks, but neither detail matters to a reader, which ignores case and
spacing. A character value is quoted and padded to its declared length, so
run one leaves the file with its trailing blanks enclosed in
quotes; the reader strips them when it stores the value.
$ gfortran m1.f90 -o m1 $ ./m1; cat config.nml wrote config.nml &CONFIG NX=100 , NY=50 , DT= 9.99999978E-03, VERBOSE=T, TITLE="run one ", /
Reading a configuration
Reading is done with read (u, nml=config), and the variables keep
whatever value they had before the statement for every name that the input does
not mention. This is what makes namelists pleasant for configuration: the
program sets sensible defaults in its declarations, and the file overrides only
what the user wants to change. The example below gives every variable a
default, then reads a file that sets just two of them, and prints all five so
that the untouched defaults are visible.
program m2
implicit none
integer :: nx, ny
real :: dt
logical :: verbose
character(len=20) :: title
namelist /config/ nx, ny, dt, verbose, title
integer :: u, ios
nx = 10
ny = 10
dt = 1.0
verbose = .false.
title = 'default'
open (newunit=u, file='config.nml', status='replace')
write (u, '(a)') '&config'
write (u, '(a)') ' nx = 200,'
write (u, '(a)') ' dt = 0.005'
write (u, '(a)') '/'
close (u)
open (newunit=u, file='config.nml', status='old')
read (u, nml=config, iostat=ios)
close (u)
print *, 'ios:', ios
print *, 'nx, ny:', nx, ny
print *, 'dt: ', dt
print *, 'verbose:', verbose
print *, 'title: ', trim(title)
end program m2
The status is zero, nx becomes 200, and ny,
verbose and title keep their default values. The
trailing comma after 200 is optional but harmless, and the input
may be spread over as many lines as the writer likes. The value of
dt prints as 0.005 with a small binary error in the last digits,
which is the usual behaviour of a binary real, not a fault of the namelist
reader.
$ gfortran m2.f90 -o m2 $ ./m2 ios: 0 nx, ny: 200 10 dt: 4.99999989E-03 verbose: F title: default
Namelists in memory
A namelist does not need a file. Any character variable can be the unit of the
read, exactly as in the internal files
article, and the nml= specifier works there too. That is
convenient for tests and for settings that arrive as a single line from a
command-line option, and it avoids creating a file just to parse one string.
The program below reads two namelist records from a character variable and
prints which variables each one changed.
program m3
implicit none
integer :: count, step
real :: scale
namelist /params/ count, step, scale
character(len=200) :: text
integer :: ios
count = 1
step = 1
scale = 1.0
text = '¶ms count = 12, step = 3 /'
read (text, nml=params, iostat=ios)
print *, 'ios:', ios, 'count:', count, 'step:', step, 'scale:', scale
count = 0
text = '¶ms scale = 2.5, count = 4 /'
read (text, nml=params, iostat=ios)
print *, 'ios:', ios, 'count:', count, 'step:', step, 'scale:', scale
end program m3
The first record sets the two integers and leaves scale at one.
The second record sets scale and count and leaves
step at the three that the first record gave it, because the
second read did not reset the variables first. Both groups fit on
one line, with values separated by commas and the group closed by the slash,
which is the same syntax as in a file. The group name after &
must match the name in the declaration.
$ gfortran m3.f90 -o m3 $ ./m3 ios: 0 count: 12 step: 3 scale: 1.00000000 ios: 0 count: 4 step: 3 scale: 2.50000000
When the input is wrong
Two mistakes are common in hand-written configuration: a name that the program
does not know, usually a typo, and a value that cannot be converted to the
variable's type. Without iostat both stop the program at run time.
With it, both produce a positive status and leave the variables as they were,
which lets the program report the problem and fall back to the defaults. The
program below tries each mistake in turn.
program m4
implicit none
integer :: n
real :: tol
namelist /options/ n, tol
character(len=120) :: text
integer :: ios
n = 5
tol = 0.001
text = '&options n = 5, bogus = 3 /'
read (text, nml=options, iostat=ios)
print *, 'unknown name, ios =', ios, 'n =', n
n = 5
tol = 0.001
text = '&options tol = "abc" /'
read (text, nml=options, iostat=ios)
print *, 'bad value, ios =', ios, 'tol =', tol, 'n =', n
end program m4
Both reads report 5010 on this runtime, a positive status that means the input
did not match the group; the exact number is processor dependent, so a program
should test it against zero rather than for a particular value. In both cases
the variables keep the values they had before the failed read. Without
iostat either statement would stop the program, which is why a
configuration reader supplies it and reports the failing record to the user;
the text of the message can be captured with iomsg, as the
files article shows for open.
$ gfortran m4.f90 -o m4 $ ./m4 unknown name, ios = 5010 n = 5 bad value, ios = 5010 tol = 1.00000005E-03 n = 5
Arrays and repetition
A namelist variable may be an array, and its values are written and read in
element order. The input can also select a section with the usual colon
notation, so grid(2:4) = 7, 8, 9 changes three elements and leaves
the others alone. Writing a namelist into a character variable shows how the
runtime formats arrays: the elements are separated by commas, and a run of
equal values is shortened with a repeat count, so the two zeroes of
origin become 2*0.00000000. The program below uses
both features.
program m5
implicit none
integer :: grid(5)
real :: origin(2)
namelist /mesh/ grid, origin
character(len=300) :: text
grid = [1, 2, 3, 4, 5]
origin = [0.0, 0.0]
write (text, nml=mesh)
print *, 'internal write:'
print *, trim(text)
grid = 0
origin = -1.0
text = '&mesh grid(2:4) = 7, 8, 9, origin = 1.5, 2.5 /'
read (text, nml=mesh)
print *, 'grid: ', grid
print *, 'origin:', origin
end program m5
The internal write produces one long record with the group name, the array
values separated by commas and the two origin values written with a repeat
count because they are equal. The read then fills elements two to four of the
grid and both elements of origin, leaving the first and last grid
elements at the zero they were set to. An array section in the input must not
run past the end of the array, because the runtime checks the bounds only when
the data is stored, at which point the program stops.
$ gfortran m5.f90 -o m5 $ ./m5 internal write: &MESH GRID=1 ,2 ,3 ,4 ,5 , ORIGIN= 2*0.00000000 , / grid: 0 7 8 9 0 origin: 1.50000000 2.50000000
Comments and repeated values
Two more conveniences make namelists usable for files that people edit by hand.
A ! starts a comment that runs to the end of the line, and a repeat
count r*c stands for r copies of the value
c, where the value may be a number or a quoted string. The program
below reads a group with both, building its text with
new_line('a') so that every statement sits on its own line, the
way it would in a real file.
program m6
implicit none
integer :: steps, counts(4)
character(len=20) :: label
namelist /run/ steps, counts, label
character(len=400) :: text
integer :: ios
steps = 0
counts = 0
label = 'none'
text = '&run' // new_line('a') // &
' steps = 12, ! how many steps' // new_line('a') // &
' counts = 3*2, 7 ! three twos and a seven' // new_line('a') // &
' label = ''trial''' // new_line('a') // &
'/'
read (text, nml=run, iostat=ios)
print *, 'ios: ', ios
print *, 'steps: ', steps
print *, 'counts:', counts
print *, 'label: ', trim(label)
end program m6
The status is zero, the first three elements of counts become 2
and the fourth becomes 7, and the quoted label keeps its four letters. The
doubled quotes inside the concatenation are how a literal quote is written in a
Fortran string, so ''trial'' in the source produces
'trial' in the text. Comments are useful for recording units or
allowed ranges next to the value, and they do not affect the read.
$ gfortran m6.f90 -o m6 $ ./m6 ios: 0 steps: 12 counts: 2 2 2 7 label: trial
Next steps
Namelists are a readable way to store settings, while the files article covers general text files and the stream and binary files article covers the compact form. Tables of numbers are better handled by the CSV and text data article, and grouped data of mixed types by the derived types article. The internal files article explains the character-variable unit used in the in-memory examples.
Source
Fortran 2018 standard (J3/18-007r1)
Fortran-lang: learning resources
In this article we have grouped variables into namelists, written a
configuration file, read it back with defaults for the missing values, used the
same mechanism on a string in memory, recognised unknown names and bad values
through iostat, and stored arrays with sections, comments and
repeat counts. The previous article,
Fortran stream and binary files, covers
the opposite end of the spectrum, where nothing is readable but everything is
exact.
Author
List all Fortran tutorials.