Input and output


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:

  1. Scan a stream of information from an input device or file.
  2. Split the stream of information into separate items.
  3. Convert each item from its external form in the input to its internal (binary) representation.
  4. Store each item in a variable.

A statement which outputs information must:

  1. Retrieve each item from a variable or specify it directly as a constant.
  2. Convert each item from its internal form to an external form suitable for output to a given device or file.
  3. Combine the items with information required to control horizontal and vertical spacing.
  4. Send the information to the appropriate device or file.

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.

The FORMAT statement

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.

Formatted input

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

The I format descriptor

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.

Example:

FORTRAN: READ 10,MEAN,INC

	10	FORMAT(I4,I4)

Input: b123b-5b

(b represents a blank). This assigns a value of 123 to MEAN and -50 to INC.

The F format descriptor

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.

Example:

FORTRAN: READ 10,X,A,B,C,D

	10	FORMAT(F4.5,F4.1,F2.2,F3.5,F3.0)

Input: b1.5b123456789bb

Results: X: 1.5 A: 12.3 B: 0.45 C: 0.00678 D: 900.0

The E format descriptor

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'.

Example:

With a format descriptor of E9.2, all the following will be read as 1.26

0.126Eb01

1.26bEb00

1.26bbbbb

12.60E-01

bbb.126E1

bbbbbb126

126bbbbbb

bbb12.6-1

Repeat count

The I, F and E format descriptors may be repeated by preceding them by a number indicating the number of repetitions. For example:

	10 FORMAT(3I4)

is equivalent to:

	10 FORMAT(I4,I4,I4)

The X format descriptor

This is used with an unsigned integer prefix n to skip n characters.

Example:

FORTRAN: READ 10,I,J

	10	FORMAT(I4,3X,I3)

Input: 123456789b

Results: I: 1234 J: 890

The T format descriptors

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.

Example:

FORTRAN: READ 10,I,J,K

	10	FORMAT(T4,I2,TR2,I2,TL5,I3)

Input: 123456789b

Results: I: 45 J: 89 K: 567

Notes:

  1. TRn is equivalent to nX.
  2. As illustrated by the example, tabs can be used not only to skip over parts of the input, but to go back and re-read parts of it.
  3. If TLn defines a position before the start of the record, the cursor is positioned at the first character. TL with a large value of n can therefore be used to return the cursor to the beginning of the record (as can T1).

Formatted output

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

Vertical spacing

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

Output: 15

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:

	10	FORMAT(I2)

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 I format descriptor

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.

Example:

	I = 15
	J = 709
	K = -12
	PRINT 10,I,J,K,
	10	FORMAT(1X,I4,I4,I4)

Output: bb15b709b-12

Notes:

  1. The first format descriptor 1X provides a space as a control character to begin output on a new line. The next descriptor I4 then prints the value 15 in a field of width 4. The same effect could be obtained by using I5 as the first descriptor, but it is clearer to use a separate descriptor for the control character.
  2. The I, F and E format descriptors may be preceded by a repetition count r, where r is an unsigned integer. Thus rIw repeats the format descriptor Iw for r repetitions. For example, the above FORMAT statement could be replaced by:
	10	FORMAT(1X,3I4)

The F format descriptor

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.

Example:

	X = 3.14159
	Y = -275.3024
	Z = 12.9999
	PRINT 10,X,Y,Z,
	10	FORMAT(1X,3F10.3)

Output: bbbbb3.142bb-275.302bbbb13.000

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 E format descriptor

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:

S0.XXXESXX

<d>

<-----w------>

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.

Example:

The value 0.0000231436 is printed as shown with the various format descriptors:

E10.4 0.2314E-04

E12.3 bbb0.231E-04

E12.5 b0.23144E-04

The literal 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.

	10 FORMAT(1X,3('RESULTS'))

More general input/output statements

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:

UNIT

FMT

ERR

END

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.

Examples:

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:

	OPEN(openlist)

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:

UNIT

FILE

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.

Example:

	OPEN(8, FILE='MYFILE.DAT')

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.

Repetition of format specifications

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.

Example:

	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)))
			

Multi-record specifications

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:

	100	FORMAT(2F10.2,F12.3//I6,2I10)

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.

Example 1:

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:

  1. Compute the conversion factor.
  2. Initialise the page number to zero.
  3. Repeat for angles in degrees from 1 to 360 in steps of 1:
    1. If the angle in degrees is one more than a multiple of 40 then:
      1. Increment the page number.
      2. Print a page header, page number and column headers, followed by a blank line.

Otherwise, if the angle in degrees is one more than a multiple of 10, then:

  1. Print a blank line.
  1. Compute the angle in radians.
  2. Print the angle in degrees and radians.

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]

NDP77
http://www.ndp77.net
webmaster Massimo F. ARENA
webmaster@ndp77.net
2004:02:14:17:30:17