.. _ch02-fortran-io: ============================================================= 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: .. code-block:: fortran 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: .. code-block:: fortran i = 4 x = 2.d0 / 3.d0 print *, 'i=', i, ' and x=', x yield .. code-block:: console 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: .. code-block:: fortran print "('i=',i3,' and x=', e17.10)", i, x or .. code-block:: fortran print 600, i, x 600 format('i=',i3,' and x=', e17.10) Each of which yield .. code-block:: console 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: .. code-block:: fortran print "('i=',i2,' and x=', e10.4)", i, x we would see .. code-block:: console i= 4 and x=0.6667E+00 Note that if the number doesn't fit in the field, asterisks will be printed instead .. code-block:: fortran i = 4000 print "('i=',i2,' and x=', e10.4)", i, x gives .. code-block:: console 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 .. code-block:: fortran 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 .. code-block:: fortran write(6,*) i, x is the same as .. code-block:: fortran 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: .. code-block:: fortran 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: .. code-block:: fortran open(unit=21, file="infile.txt") read(21,*) n close(21)