It is often useful, in Fortran and other languages, to specify where, and how you want something to print or be read. Fortran offers many formatting specifications which can serve these purposes. In the following sections we will be considering the I/O operations (OPEN, CLOSE, INQUIRE, REWIND, BACKSPACE, PRINT, READ, WRITE and NAMELIST) and I/O formatting (FORMAT).
It is worth mentioning, at this stage, what Fortran cannot do simply and directly from a language-defined perspective: Fortran will not address a file defined by a URL, files must be available locally or on a mapped network drive or equivalent. Similarly, Fortran does not natively support XML, except that XML is simple ASCII text so it can be read easily but parsing it out is down to the programmer! The Fortran language knows nothing about computer graphics; you are not going to find a language-defined draw command. Finally, Fortran does not have any language-defined mouse operations or touch screen jestures.
Modern Fortran has a rich vocabulary for I/O operations. These operations can generally be used on the screen and keyboard, external files and internal files. In recent versions of Fortran, the syntax of these commands has been rationalised but most of the original syntax has been retained for backwards compatibility. I/O operations are notoriously error-prone and Fortran now supports a unified mechanism for identifying and processing errors.
Simple I/O Operations
This is the classic "Hello World" operation, but is rarely used in production code. PRINT is one of two formatted output operations and it is also much simpler that the WRITE statement. The main purpose of the PRINT statement is to print to the screen (standard output unit) and it has no options for file output. The general form is:
PRINT fmt, list
Both fmt and list are optional and the fmt can be explicit or list-directed (as indicated by *), and being optional can take the name=value format. The list is a comma separated list of literals or intrinsic type variables. So here are some examples:
program hello implicit none integer :: i ! List-directed fmt PRINT *, "Hello World" do i = 1, 10 ! An explicit fmt and a two element list PRINT '(A,I0)', "Hello ", i enddo ! Name=value for fmt PRINT fmt='(A)', 'Goodbye' end program hello
Note that PRINT is just about the only I/O operation that still does not support IOSTAT and IOMSG clauses, and for this reason alone should not be used in new code except for temporary output and debugging. PRINT has no explicit mechanism for printing user-defined types and this is another reason for not using it in production code.
In the example on PRINT shown above, the PRINT statement is automatically pre-connected to the standard output device also known as the computer screen. However, in general, Fortran requires a two stage process to connect code to external files. First we have to connect the file to a Fortran channel (identified by a positive integer): the OPEN command, and then we can READ and WRITE to the now open channel. READ and WRITE operations to a channel that is not open, results in an error; there is no language-specified buffering until the relevant channel is opened. Once an I/O operation is complete we can CLOSE the connection between the file and the Fortran channel. If a Fortran program terminates before a channel is closed to a file, Fortran will usually close the channel without significant loss of data.
The state of availability of Fortran channels can be ascertained through one form of the INQUIRE command. The INQUIRE command can also be used to determine the existence and other properties of a file before it is connected to a Fortran channel.
Fortran I/O to internal files does not require a pre-connection process. Fortran input from the keyboard and output to the screen is automatically pre-connected on a special channel (*). Compiler vendors are free to assign a channel number to these standard I/O devices and the user can determine which channel numbers have been used via the intrinsic module ISO_FORTRAN_ENV.
The Read statement is a statement which reads from the specified input in the specified form, a variable. For example,
PROGRAM READA IMPLICIT NONE INTEGER :: A READ(*,*) A END PROGRAM
will create an integer memory cell for A, and then it will read a value with the default formatting from the default input and store it in A. The first * in (*,*) signifies where the value should be read from. The second * specifies the format the user wants the number read with. Let us first discuss the format strings available. In Fortran we have at our disposal many format strings with which we may specify how we want numbers, or character strings to appear on the screen. For fixed point reals: Fw.d; w is the total number of spaces alloted for the number, and d is the number of decimal places. The decimal place always takes up one position. For example,
PROGRAM READA IMPLICIT NONE REAL :: A READ(*,'(F5.2)') A END PROGRAM
The details of the I/O formatting e.g. '(F5.2)' will be described below
We describe explicit formatting below but it is immediately clear that there is a whole "language within a language" so Fortran provides a short cut, or language-defined format guessing. It turns out that this default formatting is very close to a comma separated variable (CSV) processor for input. List-directed I/O is specified by a fmt=* clause, but the fmt clause is optional and can be replaced with just *.
Fortran has a rich, but very terse, language for controlling the formatting of I/O operations. The format commands can be placed in an explicit FORMAT statement or they can be placed within a clause of the relevant READ or WRITE statement either literally or stored in a CHARACTER variable.
There are limitations: Fortran is concerned with character I/O and not with presentational properties such as the size or font. Fortran has very limited capabilities for random access especially on output. However, it is very simple for the Fortran programmer to output files that conform to modern CSS and HTML standards and to control output appearance accordingly when the file is accessed via a browser.