This chapter introduces input, output and format statements which give us greater flexibility than the simple READ and PRINT statements used so far.
A statement which reads information must:
A statement which outputs information must:
The simple READ statement:
READ *, variable_list
reads a line (or record ) of information from the standard input (defined as the keyboard for programs run from a terminal) and stores it in the variables in variable_list. The asterisk refers to a list-directed format used to split the information into separate items using spaces and/or commas as separators and convert each item to the appropriate internal representation, which is determined by the type of the corresponding variable in variable_list.
Similarly, the simple PRINT statement:
PRINT *, output_list
uses a list-directed format to convert each constant, and the value of each variable, in output_list to a suitable form for output on standard output (defined for a program run from a terminal as the screen) and prints the list as a line of output, with spaces between the items.
We can obtain greater control over the conversion and formatting of input/output items by replacing the asterisk in a READ or PRINT statement by the label of a FORMAT statement, for example:
READ 10,A,B,C . 10 FORMAT(...)
The FORMAT statement describes the layout of each item to be read or printed, and how it is to be converted from external to internal form or vice versa. It also describes the movements of an imaginary cursor which can be envisaged as scanning the input list. Its general form is:
label FORMAT (specification_list)
label is a statement label. A FORMAT statement must always be labelled to provide a reference for use in input/output statements.
specification_list is a list of format descriptors (sometimes called edit descriptors), separated by commas. These describe the layout of each input or output item, and specify how it is to be converted (or edited) from external to internal form or vice versa.
FORMAT statements can be placed anywhere in a program. It is often convenient to place them all at the end (immediately before END), especially if some of them are used by more than one input/output statement.
The format descriptors used for input are summarised in Figure 14 and described in the following sections.
Descriptor Meaning Iw Convert the next w characters to an INTEGER value. Fw.d Convert the next w characters to a REAL value. If no decimal point is included, the final d digits are the fractional part. Ew.d Convert the next w characters to a REAL value, interpreting them as a number in exponential notation. nX Skip the next n characters. Tc Skip to character position c. TLn Skip to the character n characters to the left of the current character. TRn Skip to the character n characters to the right of the current character.
Figure 14: Some format descriptors for input
This is used to read a value into an INTEGER variable. Its form is Iw, where w is an unsigned integer indicating the number of characters to be read (the width of the field). These characters must consist of decimal digits and/or spaces, which are interpreted as zeroes, with an optional + or - sign anywhere before the first digit. Any other characters will cause an input error.
FORTRAN: READ 10,MEAN,INC
(b represents a blank). This assigns a value of 123 to MEAN and -50 to INC.
This is used to read a value into a REAL variable. It has the form Fw.d, where w is an unsigned integer representing the width of the field and d is an unsigned integer representing the number of digits in the fractional part.
The corresponding input item must consist of decimal digits and/or spaces, with an optional sign anywhere before the first digit and an optional decimal point. As with the I format descriptor, spaces are interpreted as zeroes. If there is no decimal point in the item, the number of fractional digits is indicated by d. If the item includes a decimal point, d is ignored, and the number of fractional digits is as indicated.
FORTRAN: READ 10,X,A,B,C,D
Results: X: 1.5 A: 12.3 B: 0.45 C: 0.00678 D: 900.0
This is used to read a value into a REAL variable. It has a similar form to the F format descriptor, but is more versatile, as it can be used to read input in exponential notation.
We saw in Chapter Two that a REAL constant can be written in exponential notation as a REAL or INTEGER constant followed by an exponent in the form of the letter 'E' followed by the power of 10 by which the number is to be multiplied. For input, the exponent can also be a signed integer without the letter 'E'.
With a format descriptor of E9.2, all the following will be read as 1.26
The I, F and E format descriptors may be repeated by preceding them by a number indicating the number of repetitions. For example:
is equivalent to:
This is used with an unsigned integer prefix n to skip n characters.
FORTRAN: READ 10,I,J
Results: I: 1234 J: 890
The T (for tab), TL and TR format descriptors are used to move the cursor to a given position. This is defined absolutely by the T format descriptor or relative to the current position by the TL and TR descriptors.
FORTRAN: READ 10,I,J,K
Results: I: 45 J: 89 K: 567
Output statements use the same format descriptors as for input and another, the literal format descriptor, which is a string of characters for output. The descriptors are summarised in Figure 15 and described further in the following sections.
Descriptor Meaning Iw Output an INTEGER value in the next w character positions Fw.d Output a REAL value in the next w character positions, with d digits in the fractional part. Ew.d Output a REAL value in exponential notation in the next w character positions, with d digits in the fractional part. nX Skip the next n character positions. Tc Skip to character position c. TLn Skip to the character n characters to the left of the current character. TRn Skip to the character n characters to the right of the current character. 'c1c2...cn Output the string of n characters c1c2...cn starting at the ' next character position. nHc1c2...c Output the string of n characters c1c2...cn starting at the n next character position.
Figure 15: Some format descriptors for output
As well as defining the layout of a line of output via an associated FORMAT statement, an output statement must define the vertical placement of the line on the screen or page of printed output. The method of doing this is described before the use of the format descriptors of Figure 15.
The computer uses the output list and the corresponding format specification list to build each line of output in a storage unit called an output buffer before displaying or printing it. When the contents of the buffer are displayed on the screen or printed on paper, the first character is not shown, but is interpreted as a control character, defining the vertical placement of the line. Four control characters are recognised, as shown in Figure 16.
Character Vertical spacing before output Space One line 0 (zero) Two lines 1 New page + No vertical spacing (i.e. Current line is overprinted).
Figure 16: Control characters for vertical spacing
The effect of any other character is not defined, but is usually the same as a space, i.e. output is on the next line.
Incorrect output may be obtained if the control character is not taken into account. It is therefore best to use the format specification to insert a control character as the first character in a line, rather than to provide it via the output list. For example:
N = 15 PRINT 10,N 10 FORMAT(1X,I2)
Buffer contents: b15
The initial blank in the buffer is interpreted as a control character, and '15' is printed on the next line. However, if the FORMAT statement were:
the buffer contents would be '15'. On printing, the initial '1' would be interpreted as a control character, and '5' would be printed at the start of the next page.
The following sections describe in more detail the effect of the format descriptors in output statements.
The format descriptor Iw is used to print an INTEGER value right-justified in a field of width w character positions, filling unused positions on the left with blanks and beginning with a '-' sign if the value is negative. If the value cannot be printed in a field of width w, the field is filled with asterisks and an output error is reported.
I = 15 J = 709 K = -12 PRINT 10,I,J,K, 10 FORMAT(1X,I4,I4,I4)
The format descriptor Fw.d (F for floating point) is used to print a REAL value right-justified in a field of width w, with the fractional part rounded (not truncated) to d places of decimals. The field is filled on the left with blanks and the first non-blank character is '-' if the value is negative. If the value cannot be printed according to the descriptor, the field is filled with asterisks and an error is reported.
X = 3.14159 Y = -275.3024 Z = 12.9999 PRINT 10,X,Y,Z, 10 FORMAT(1X,3F10.3)
The value of X is rounded up, that of Y is rounded down, and that of Z is rounded up, the 3 decimal places being filled with zeroes.
The format descriptor Ew.d is used to print a REAL value in exponential notation right-justified in a field of width w, with the fractional part rounded to d places of decimals. Thus the layout for a format descriptor of E10.3 is:
S indicates a position for a sign. The initial sign is printed only if negative, but the sign of the exponent is always printed.
X indicates a digit.
The value 0.0000231436 is printed as shown with the various format descriptors:
The literal format descriptors 'c1c2...cn' and nHc1c2...cn place the string of n characters c1c2...cn directly into the buffer. Thus a PRINT statement using either of the following FORMAT statements will print the header: 'RESULTS' at the top of a new page:
10 FORMAT('1','RESULTS') 10 FORMAT(1H1,7HRESULTS)
The quoted form is generally easier to use, but the 'H' form is convenient for providing control characters.
A repetition count may be used with a literal format descriptor if the descriptor is enclosed in parentheses, e.g.
A record is a sequence of values or characters.
A file is a sequence of records.
An external file is one contained on an external medium (e.g. a magnetic disk).
Each FORTRAN input/output statement reads information from, or writes it to, a file. The file must be connected to an external unit, i.e. a physical device such as the keyboard or screen, or a magnetic disk. An external unit is referred to by a unit identifier, which may be:
The READ and PRINT statements we have considered so far read from the file 'standard input', normally connected to the keyboard, and print on the file 'standard output', normally connected to the screen. To use different files and devices and to obtain various other options, we require a more general form of the READ statement for input, and a new statement, the WRITE statement for output. These statements have the form:
READ (cilist) input_list
and WRITE (cilist) output_list
where cilist is a list of input-output specifiers, separated by commas. Each specifier takes the form:
keyword = value
The specifiers may be in any order. In special cases noted below, only the value is required. Some of the keywords are:
The unit specifier must always be included. Its value must be a unit identifier, as defined above.
If the unit specifier is the first item in cilist, it may be denoted by its value only (without 'UNIT=').
Unit identifiers 5 and 6 are preconnected to the files 'standard input' and 'standard output' respectively.
The value of the format specifier FMT is the label of a FORMAT statement to be used for input/output conversion, or an asterisk to indicate list-directed formatting. A format specifier may be denoted by its value only (without 'FMT=') if it is the second item in cilist and follows a unit specifier also denoted by its value only.
If unit identifier 5 corresponds to standard input, the following are all equivalent:
READ(UNIT=5,FMT=100) X,Y,Z READ(FMT=100,UNIT=5) X,Y,Z READ(5,FMT=100) X,Y,Z READ(5,100) X,Y,Z READ(*,100) X,Y,Z
Also, the statements:
READ(*,*) A,B,C and READ(5,*) A,B,C
are both equivalent to the list-directed input statement:
READ *, A,B,C
The last two specifiers deal with special conditions. If an error occurs in input or output execution normally stops, but if an error specifier of the form:
ERR = label
is included in cilist, execution continues from the statement labelled label. This makes it possible to include statements in the program to take special actions to deal with such errors.
If a READ statement tries to read more data than is available, an input error normally occurs. However, if a file ends with a special end-of-file record, a specifier of the form:
END = label
will cause execution to continue from the statement labelled label.
The OPEN statement
As noted above, the files 'standard input' and 'standard output' are preconnected to unit identifiers 5 and 6, and normally refer to the keyboard and screen, respectively. If other files, e.g. files on disk, are to be used, or if 'standard input' and 'standard output' are to be redefined, each file must be connected to an external unit by an OPEN statement, which has the form:
where openlist is a list of specifiers of the form:
keyword = value
Specifiers may occur in any order. Two of the more important keywords are:
The unit specifier must be included. Its value must be a unit identifier.
If the unit specifier is the first item in openlist, it may be denoted by its value only (without 'UNIT=').
The value of the file specifier is a character expression naming a file to be opened, i.e. connected to the external unit specified by the unit specifier. If the file does not exist, a new file is created.
connects the file MYFILE.DAT to unit 8. If the file does not exist, it is created. READ and WRITE statements referring to this unit identifier will then read from or write to this file.
If the number of items in an input or output list exceeds the number of format descriptors in the corresponding FORMAT statement, a new record is taken (a new line for terminal input/output) and the format specification list is re-used. This happens as often as required to deal with the complete list.
READ(5,10) A,B,C,P,Q,R,X,Y,Z 10 FORMAT(3F12.3)
This reads three values from the first line of input into the variables A,B and C, from the second line into P,Q and R, and from the third line into X,Y and Z. Similarly:
WRITE(6,10) A,B,C,P,Q,R,X,Y,Z 10 FORMAT(1X,3F12.3)
prints the values of the variables three to a line on consecutive lines.
The format specification list may also be re-used partially if it includes nested parentheses. The rules are:
This is illustrated by the following examples, in which an arrow indicates the point from which repetition, if required, begins:
10 FORMAT(I6,10X,I5,3F10.2) 20 FORMAT(I6,10X,I5,(3F10.2)) 30 FORMAT(I6,(10X,I5),3F10.2) 40 FORMAT(F6.2,(2F4.1,2X,I4,4(I7,F7.2))) 50 FORMAT(F6.2,2(2F4.1,2X,I4),4(I7,F7.2)) 60 FORMAT(F6.2,(2(2F4.1,2X,I4),4(I7,F7.2)))
Repetitions can be used as in the last section to read in or print out a sequence of values on consecutive lines using the same format specification list. It is also useful to be able to specify the format of several consecutive lines (or records) in a single format specification. This can be done using the / format descriptor, which marks the end of a record. Unlike other format descriptors, / need not be preceded or followed by a comma.
On input, / causes the rest of the current record to be skipped, and the next value to be read from the first item on the next record. For example:
READ(5,100) A,B,C,I,J,K 100 FORMAT(2F10.2,F12.3/I6,2I10)
reads three REAL values into A,B and C from a line, ignores anything more on that line, and reads three INTEGER values into I,J and K from the next line.
Consecutive slashes cause records to be skipped. Thus if the FORMAT statement in the above example were changed to:
a complete line would be skipped before the values were read into I,J and K.
On output, a / marks the end of a record, and starts a new one. Consecutive slashes cause blank records to be output. For example:
WRITE(6,200) A,B,A+B,A*B 200 FORMAT(1H1////T10,'MULTIPLE LINES EXAMPLE'/// * 1X,'THE SUM OF',F5.2,' AND',F5.2,' IS',F5.2/ * 1X,'AND THEIR PRODUCT IS',F8.2////)
prints four blank lines and a header at the top of a new page, followed by two blank lines, then the sum and product on consecutive lines followed by four blank lines.
The following example illustrates the use of formatting to produce output in tabular form with headers and regular spacing.
Rewrite the degrees to radians conversion program (Chapter 6, Example 2) to print angles from 1 to 360 degrees in 1 degree intervals and their equivalents in radians. The results should be printed 40 lines to a page, with the values suitably formatted, blank lines separating groups of 10 consecutive lines, headers for the 'Degrees' and 'Radians' columns, and a header and page number at the start of each page.
The outline is:
Otherwise, if the angle in degrees is one more than a multiple of 10, then:
and the program follows:
PROGRAM ANGLES INTEGER DEGREE,PAGENO,OUT DATA OUT/6/ C UNIT NUMBER FOR OUTPUT. A DIFFERENT DEVICE COULD BE USED BY C CHANGING THIS VALUE DATA PAGENO/0/ CONFAC = 3.141593/180.0 C CONVERSION FACTOR FROM DEGREES TO RADIANS DO 10, DEGREE = 1,360 N = DEGREE-1 IF (N/40*40 .EQ. N) THEN C PRINT PAGE HEADER, NUMBER AND COLUMN HEADERS PAGENO = PAGENO+1 WRITE(OUT,100)PAGENO ELSE IF (N/10*10 .EQ.N) THEN WRITE(OUT,110) END IF RADIAN = DEGREE*CONFAC 10 WRITE(OUT,120)DEGREE,RADIAN 100 FORMAT(1H1//1X,'DEGREES TO RADIANS CONVERSION TABLE', * T74,'PAGE',I2//1X,'DEGREES RADIANS'/) 110 FORMAT(1X) 120 FORMAT(1X,I5,T10,F7.5) END
Figure 17: Degrees to radians conversion program (version 3)
[Contents] [Previous] [Next] [Home]
webmaster Massimo F. ARENA