Fortran Input/Output

Ultimately we need some way to output the results of our computations. This could be in the form of data files that get post-processed by other programs (e.g. for visualization), or it could be output to the terminal to give diagnostics and status updates to the user.

Printing to the terminal

Inputs and outputs can either be unformatted or formatted. Unformatted outputs have their structure determined by the compiler based on the various types involved. Formatted IO lets you determine the structure of what gets printed (or read in).

print statements are used for printing information to the terminal. In unformatted mode the syntax is as follows:

print *, 'x = ', x

The asterisk indicates that this is an unformatted print statement. Following that there can be any number of variables or character strings separated by commas. All of these statements will get printed one after the other on one line, and a line break will be automatically inserted at the end. This prints the string “x = “ followed by whatever is stored in x with a format chosen by the compiler based on what type it is.

As another example, the statements:

i = 4
x = 2.d0 / 3.d0
print *, 'i=', i, ' and x=', x

yield

i=           4  and x=  0.666666687

To have more control over the format, a formatted print statement can be used. A format can be placed directly in the statement in place of the * , or can be written separately with a label, and the label number used in the print statement.

For example, if we wish to display the integer i in a field of 3 spaces and print x in scientific notation with 10 digits after the decimal points in a field that is 17 digits wide, we could do:

print "('i=',i3,' and x=', e17.10)", i, x

or

print 600, i, x
600 format('i=',i3,' and x=', e17.10)

Each of which yield

i=  4 and x= 0.6666666667E+00

Note that there are two leading spaces before the 4, and one before the floating point number. The 4 is right-justified in a field of 3 characters after the 'i=' string. Similarly, the floating point number is right-justified in a field 17 characters, but only requires 16.

For comparison, if we use:

print "('i=',i2,' and x=', e10.4)", i, x

we would see

i= 4 and x=0.6667E+00

Note that if the number doesn’t fit in the field, asterisks will be printed instead

i = 4000
print "('i=',i2,' and x=', e10.4)", i, x

gives

i=** and x=0.6667E+00

Writing to a file

Instead of printing directly to the terminal, we will often want to write results out to a file. This can be done using the open statement to open a file and attach it to a particular unit number, and then use the write statement to write to this unit

open(unit=20, file='output.txt')
write(20,*) i, x
close(20)

This would do an unformatted write to the file output.txt instead of writing to the terminal. The * in the write statement can be replaced by a format, or a format label, as with print statements.

There are many other optional arguments to the open command.

Unit numbers should generally be larger than 6. By default, unit 6 refers to the terminal for output, so

write(6,*) i, x

is the same as

print *, i, x

Question How can you write results to a file with a formatted style?

Reading input

Reading input works in essentially the same way as printing. For example, you could do an unformatted read into the variable n by:

print *, "Please input n... "
read *, n

Similarly, you can read from a file with a syntax that closely matches write statements. In this case each read statement will process one line in the file, so you will need multiple read calls to process files with multiple lines.

For example, you could read from a file into the variable n by:

open(unit=21, file="infile.txt")
read(21,*) n
close(21)