We have some choices when we read input or write output. Often we use the 'default format', as in:
READ *, A, B
PRINT *, A, B
If we want more control over the process, we can use the FORMAT statement, which contains a 'format string', or we can include a format string in the READ or PRINT statements.
Examples of READ
READ *, NUM ! use the default format
READ 200, NUM1, NUM2 ! use the FORMAT statement labeled 200
READ '(I3,2X,I7'), NUM1, NUM2 ! use the quoted format string
For the second READ statement to make sense, we need to have a statement of the form:
200 FORMAT(I3,2X,I7)
Examples of PRINT
PRINT *, NUM ! use the default format
PRINT 150, NUM, NUM2 ! use the FORMAT statement labeled 200
PRINT '(I7,4X,I6)', NUM1, NUM2 ! use the quoted format string
For the second PRINT statement to make sense, we need to have a statement of the form:
150 FORMAT(I7,4X,I6)
Default Format for Input
If we want to read using the default format, the input record should contain a sequence of values separated by (one or more) blanks. The values should match the types of data of the variables listed to receive those values.
For an INTEGER variable, the input value should a sequence of digits perhaps preceded by a plus or minus sign.
For a REAL value, the input value should be a sequence of digits perhaps including one decimal point.
For a CHARACTER variable, the input value should be enclosed in quotation marks. (It is legal to have an empty string '' as a value.) The quotation marks are not part of the value but serve as delimiters.
If there are not enough values in the input record to match the variables listed, reading continues with the next record.
It is possible to have repeated values in input. This involves using a repetition factor; we could have n*value in the input. An example might be:
14 567 3*72
where this line is considered now to contain 5 input integer values.
Default Format for Output
When we write output using the default format, the appearance of numeric values is not entirely predictable. Numeric values are written separated by blanks. INTEGER values are printed using the number of digits needed for the largest available integer value, without leading zeroes, preceded by a minus sign if appropriate. REAL values are printed using either the E or F format depending on the size of the number.
CHARACTER variables and literals are printed in their exact length without preceding or following blanks.
A LOGICAL value is written as 'T' for the value .TRUE. or 'F' for the value .FALSE..
Lines are printed are (by default) single-spaced.
Format Strings
A format string is a list of descriptors and literals, usually separated by commas, enclosed in parentheses. It may be coded into a READ, WRITE or PRINT statement, as in
PRINT '(A8,1X,I4)', NAME, NUM
or it may be the body of a FORMAT statement, as in
200 FORMAT(A8,1X,1X,I4)
in which case we refer to it by the label on the FORMAT statement, as in PRINT 200, NAME, NUM
A format string can contain format substrings marked with extra parentheses, and such substrings can have repetition factors. An example of this might be
(A7,4(2X,I3),A5)
which is equivalent to
(A7,2X,I3,2X,I3,2X,I3,2X,I3,A5)
Substrings can be useful when we want to read or write a number of value of the same type, perhaps using an array.
Output Descriptors
Note: This list is not exhaustive. In particular, it does not cover DOUBLE PRECISION or COMPLEX values, and it does not cover scale factors.
Note about the following: The I, F, E, A and L descriptors can all be prefixed with repetition factors. We might have 3I4, 4F6.2, or 2A10.
The I descriptor is for INTEGER values. The value is printed, right-justified, in w spaces. If n is specified, then at least n digits will be printed; this can result in leading zeroes.
If the value is negative, a leading minus sign is printed (and uses up one of the w spaces.) If the value is positive, no plus sign is printed, by default, but the SP descriptor can be used to change this behavior. (See the SP, SS and S descriptors.)
If the value is too large to be printed in w spaces, the result is that w asterisks ('*') are printed instead. If the value is too small to need w spaces, we have leading blanks in place of leading zeroes.
The F descriptor is for REAL values. The value is printed, right-justified, in w spaces, with d digits to the right of the decimal point. We may have trailing zeroes.
If the value is negative, a leading minus sign is printed (and uses up one of the w spaces.) If the value is positive, no plus sign is printed, by default, but the SP descriptor can be used to change this behavior. (See the SP, SS and S descriptors.)
If the value is too large to be printed in w spaces, the result is that w asterisks ('*') are printed instead. If the value is too small to need w spaces, we have leading blanks in place of leading zeroes. (The digit immediately left of the decimal point will be printed even if it is 0.)
In general, we need to have w >= d + 3.
The E descriptor is for REAL values. The value is printed, right-justified, in w spaces in "normalized" form: a minus sign (if appropriate), a leading zero, a decimal point, d significant digits, 'E', and then the exponent, which will include its own leading plus or minus sign. The significant digits may include trailing zeroes, and the exponent may include leading zeroes.
If e is specified, then the exponent will be printed using e spaces. The default value of e is 4.
If the value is negative, a leading minus sign is printed (and uses up one of the w spaces.) If the value is positive, no plus sign is printed, by default, but the SP descriptor can be used to change this behavior. (See the SP, SS and S descriptors.)
If the value is too large to be printed in w spaces, the result is that w asterisks ('*') are printed instead. If the value is too small to need w spaces, we have leading blanks in place of leading zeroes. (The digit immediately left of the decimal point will be printed even if it is 0.)
In general, we need to have w >= d + 7, for the first form, or w >= d + e + 5, for the second form.
The A descriptor is for CHARACTER values. The value is printed right-justified in w spaces.
If w is not specified, the value is printed using as many spaces as are needed.
If the value is longer than w characters, it will be truncated on the right. If the value is shorter than w characters, the w spaces will be padded with blanks on the left as needed.
(Another way to write a CHARACTER constant is simply to include it as a literal in the format string.)
The L descriptor is for LOGICAL values. The value is printed in w spaces, either 'T' for .TRUE. or 'F' for .FALSE., right-justified after w - 1 spaces.
The nX descriptor inserts n blanks. The default value of n is 1.
The T descriptor is used to move left or right in the output record.
Tn means "go to column n".
TLn means "go left n columns". (If n is too large, this goes to column 1.)
TRn means "go right n columns".
The slash descriptor means "continue output in column 1 of the next line."
It may occur anywhere and need not be separated from other descriptors by commas. We could have several consecutive slashes.
The S, SS and SP descriptors are used to switch on and off the printing of leading plus signs for positive numeric values.
SP means "start printing leading plus signs as needed".
SS means "start suppressing leading plus signs".
S means "give control of this matter back to the system".
Input Descriptors
Note about the following: The I, F, E, A and L descriptors can all be prefixed with repetition factors. We might have 3I4, 4F6.2, or 2A10.
Note: This list is not exhaustive. In particular, it does not cover DOUBLE PRECISION or COMPLEX values, and it does not cover scale factors.
The I descriptor is for INTEGER values. It reads w characters, expecting to find digits, blanks, and perhaps a leading plus or minus sign (which counts as one of the w characters). The leading plus sign is optional in any case.
Blanks within the field may be interpreted as zeroes or they may be ignored. (See the BN and BZ descriptors and the BLANK optional parameter for OPEN.) Leading blanks are interpreted as zeroes either way. Thus, for instance, if we interpret ' 12 3 45 ' as I9, the value is 12030450.
If a comma is used as a field separator in the input record, its presence will mark the end of the field, even if the result is less than w spaces wide.
The I descriptor is for REAL values. The input field, w spaces wide, is expected to contain possible leading blanks, an optional plus or minus sign, and digits, possibly interrupted by a decimal point.
The input value may have more digits than a REAL can contain, in which case the value is assigned by the usual rules.
If the decimal point is present, its location overrides the value of d. If no decimal point is present, the rightmost d digits are used as the digits right of the decimal point.
Blanks within the field may be interpreted as zeroes or they may be ignored. (See the BN and BZ descriptors and the BLANK optional parameter for OPEN.) Leading blanks are interpreted as zeroes either way.
If a comma is used as a field separator in the input record, its presence will mark the end of the field, even if the result is less than w spaces wide.
The A descriptor is for CHARACTER values.
If w is specified, the value consists of the next w characters in the input. This will be assigned to the corresponding variable by the usual assignment rules.
If w is not specified, the width will be the length of the corresponding variable.
The L descriptor is for LOGICAL values. The input field, w characters wide, is expected to contain optional leading blanks, an optional period, either 'T' for .TRUE. or 'F' for .FALSE., and optional trailing characters (which will be ignored).
The nX descriptor skips over the next n columns. The default value of n is 1.
The T descriptor is used to move left or right in the input record. (This means a given field could be read more than once.)
Tn means "go to column n".
TLn means "go left n columns". (If n is too large, this goes to column 1.)
TRn means "go right n columns".
The slash descriptor means "ignore the rest of this record and continue at the beginning of the next record." It may occur anywhere and need not be separated from other descriptors by commas. We could have several consecutive slashes.
The BN and BZ descriptors are used to switch on and off the interpretation as zeroes of blanks inside a numeric input field.
BZ means "interpret a blank as a zero".
BN means "ignore blanks".
Either way, leading blanks will be interpreted as zeroes, and a field which is all blanks will be interpreted as all zeroes.
Further Comments
One of the reasons to use a FORMAT statement is that we may want to print a number of lines using the same format. If we hard-code the format string into our PRINT statements, then (a) we have to do more work, typing the same string repeatedly, and (b) if we decide later that we want to change it slightly, we will need to make changes in a number of places instead of one. Using FORMAT statements is therefore a convenience.
FORMAT statements are considered data and are not executable code. They may occur anywhere in a program; the compiler will recognize their nature and not attempt to execute them. It makes sense, however, to list them not too far from where they are used.