Input / output

Programs communicate with the outside world by accepting data and by returning results. It is quite possible that no data need be passed to the program, for instance if it is meant to perform a computation for which all data has been provided in the program, through DATA and PARAMETER statements. Also, the output of a program need not look like numbers or text, for instance if the program controls some device such as a rocket engine.

Fortran has three statements for input and output: the READ statement for input, and WRITE and PRINT for output. These statements take various forms depending on how much you want to specify their behaviour. We will start with the simplest form, the `list-directed' I/O, where the programmer does not specify anything about the form of the input and output. Then we go on to `formatted' I/O where specifies such matters as how many decimal digits get printed. (Btw, there is also `unformatted I/O'. This means that the data is read/written as raw, machine-dependent data. This form of I/O is faster to process than any other, but you can not carry such files to another machine.)

For many programs the input comes from one source, and output need be directed to one point only, default devices, often the keyboard and the screen, respectively. If the operating system allows redirection of I/O channels, it is also easy to accept input from and write output to an external file. However, in some cases the input comes from several sources (files) or output has to be written to more than one external device. For this we discuss output to general external devices.

List-directed I/O

In list-directed I/O, system rules are followed for the form in which input is accepted and output is generated. The programmer only specifies what data is handled, not how it is handled.

I/O to/from a default device

The list directed PRINT statement looks like
      PRINT *,list
where the list can contain variables, array elements, character variables, array names, implied DO lists, and expressions. If the list is empty (in which case the comma has to omitted) only a blank line is output. Otherwise, all elements of the list are output on a single line, with a space preceding each one.

List-directed WRITE is done by leaving the format of a formatted WRITE unspecified.

The list-directed READ statement looks like

      READ *,list
The items in the input are separated by spaces, and they may be converted to the right type depending on the variables in the list they are assigned to.

I/O to/from other devices

The PRINT statement can only address the default device. However, the READ and WRITE statements can address arbitrary devices. First of all, here is how to perform list-directed I/O on external devices:
      READ (UNIT=un,FMT=*) list
      WRITE (UNIT=un,FMT=*) list
If the unit is specified as `*', the default device is used, normally the keyboard and screen respectively. These often have unit number 5 and 6 respectively.

Apart from UNIT and FMT, other, optional, specifiers are possible, eg related to errors in the transmission. Specifiers can appear in any order, but if the unit specification immediately follows the left parenthesis, and the format is on the second place, the keywords and the equal signs can be omitted. Eg,

      READ (*,*) list
      WRITE (*,*) list
for accessing the installation-dependent default devices.

Formatted I/O

If you want more control over how your output appears, or if your input was written using some strict rules, you can use the following formatted I/O statements.
      PRINT fmt,list
      READ (UNIT=un,FMT=fmt) list
      WRITE (UNIT=un,FMT=fmt) list
The most common ways of specifying the format are
      '(fmt-spec)'
      (fmt-spec)
There are a few more ways, but they are obscure. The format specification is discussed below.

Formats

The FORMAT statement is a labeled statement
label FORMAT(fmt-spec)
that is referenced in a formatted I/O statement. Depending on your personal preferences you can place the format statement close to the I/O statement, or at the end of the program unit, or anywhere else in the program unit.

Format specification


A format specification is a list of one or more format codes, separated by commas. Example: 1X,3I5. The format specification determines how the I/O list in a PRINT, WRITE, or READ statement is handled.

Carriage control

In printed output, the first column of a record often serves as carriage control: it determines whether this record is print on a new line, a new page, or such. To prevent mishaps such as a large stack of paper with one line per sheet, format specifications for output should start with ' ' or 1X, to generate a space which causes the carriage to move to the next output line.

More I/O list than format specification

If there are more items in the I/O list than in the format specification, the format is repeated after going to the next record. Example:
      PRINT '(3(1X,I3))',(a(i),i=1,100)
will output 100 integers, on lines of 3 each.

More format specification than I/O list

If there are more specifications in the format than there are I/O items in the action that uses the format, the remaining specifications are ignored. Example:
      PRINT '(100(1X,I3))',(a(i),i=1,3)
will output one line of 3 integers. An example that also uses the previous point: suppose that unit 10 is connected to a file that has at least 10 lines of 4 integers, then
      READ (UNIT=12,FMT=10) (a(i),i=1,30)
10    FORMAT(3(I3,1X))
will read 3 integers from each line, for a total of 10 lines. If there are superfluous specifications in a WRITE or PRINT statement, these are ignored also, except that character constants and such are processed. To prevent these, the colon specifier will terminate the format completely if there no more items in the I/O list.

Error conditions

Every READ starts at a new record (input line). If there is more data on a line than the READ statement requires, excess data is ignored. If there is not enough data on the input line to satisfy the READ statement, the operation is terminated and the remaining variables are unaltered. If the input line ended in a slash, the read is successfully terminated, otherwise an error occurs.