Input and Output |
5 |
![]() |
This chapter describes the general concepts of FORTRAN input and output, and provides details on the different kinds of I/O. See also the Input/Output chapter in the Sun Fortran Programmer's Guide.
Any operating system based on the UNIX operating system is not as record-oriented as FORTRAN. This operating system treats files as sequences of characters instead of collections of records. The FORTRAN runtime system keeps track of file formats and access mode during runtimes. It also provides the file facilities, including the FORTRAN libraries and the standard I/O library.
The FORTRAN default value for the maximum number of logical units that a program can have open at one time is 64. For current Solaris releases, this limit is 256. A FORTRAN program can increase this limit beyond 64 by calling the setrlim() function. See the man page setrlim(2). If you are running csh, you can also do this with the limit or unlimit command; see csh(1).
The standard logical units 0, 5, and 6 are preconnected to Solaris as stderr, stdin, and stdout, respectively. These are not actual file names, and cannot be used for opening these units. INQUIRE does not return these names, and indicates that the above units are not named unless they have been opened to real files. However, these units can be redefined with an OPEN statement. The names, stderr, stdin, and stdout, are meant to make error reporting more meaningful. To preserve error reporting, the system makes it is an error to close logical unit 0, although it can be reopened to another file. If you want to open a file with the default file name for any preconnected logical unit, remember to close the unit first. Redefining the standard units can impair normal console I/O. An alternative is to use shell redirection to externally redefine the above units. To redefine default blank control or the format of the standard input or output files, use the OPEN statement, specifying the unit number and no file name, and use the options for the kind of blank control you want.Any error detected during I/O processing causes the program to abort, unless alternative action has been provided specifically in the program. Any I/O statement can include an ERR= clause (and IOSTAT= clause) to specify an alternative branch to be taken on errors and return the specific error code. Read statements can include END=n to branch on end-of-file. File position and the value of I/O list items are undefined following an error. END= catches both EOF and error conditions; ERR= catches only error conditions.
If your program does not trap I/O errors, then before aborting, an error message is written to stderr with an error number in square brackets, [ ], and the logical unit and I/O state. The signal that causes the abort is IOT. Error numbers less than 1000 refer to operating system errors; see intro(2). Error numbers greater than or equal to 1000 come from the I/O library. For external I/O, part of the current record is displayed if the error was caused during reading from a file that can backspace. For internal I/O, part of the string is printed with a vertical bar (|) at the current position in the string.Do not reference a function in an I/O list if executing that function causes an I/O
statement to be executed. Example:
WRITE( 1, 10) Y, A + 2.0 * F(X) ! Wrong if F() does I/O |
The four kinds of I/O are: formatted, unformatted, list-directed, and NAMELIST.
The two modes of access to files are sequential and direct. When you open a file, the access mode is set to either sequential or direct. If you do not set it explicitly, you get sequential by default. The two types of files are: external files and internal files. An external file resides on a physical peripheral device, such as disk or tape. An internal file is a location in main memory, is of character type, and is either a variable, substring, array, array element, or a field of a structured record.I/O combinations on external files are:
The following table shows combinations of I/O form, access mode, and
physical file types.
You get a print file by using the nonstandard FORM='PRINT' in OPEN.
OPEN ( ..., FORM='PRINT', ... ) |
This specifier works for sequential access files only.
A print file has the following features:
In general, if you open a file with FORM='PRINT', then for that file list-directed output does not provide the FORTRAN Standard blank in column one; otherwise, it does provide that blank. FORM='PRINT' is for one file per call.
If you open a file with FORM='PRINT', then that file has the same content as if it was opened with FORM='FORMATTED', and filtered with the output filter, asa. If you compile with the -oldldo option (old list-directed output), then all the files written by the program do list-directed output without that blank in column one; otherwise, they all get that blank. The -oldldo option is global.The INQUIRE statement returns 'PRINT' in the FORM variable for logical units opened as print files. It returns -1 for the unit number of an unopened file.
If a logical unit is already open, an OPEN statement using the BLANK option does nothing but redefine that option.
As a nonstandard extension, if a logical unit is already open, an OPEN statement using the FORM option to switch betweenFORM='PRINT'
and FORM='FORMATTED'
does nothing but redefine that option. OPEN( UNIT=6, FORM='PRINT') |
Scratch files are temporary files that normally disappears after execution is completed.
Example: Create a scratch file:OPEN( UNIT=7, STATUS='SCRATCH' ) |
Example: Close a scratch file that you want to access later:
CLOSE( UNIT=7, STATUS='KEEP' ) |
Remember to get the real name of the scratch file. Use INQUIRE if you want to reopen it later.
Traditional FORTRAN environments usually assume carriage control on all logical units. They usually interpret blank spaces on input as zeroes, and often provide attachment of global file names to logical units at runtime. The routine IOINIT(3F) can be called to specify these I/O control parameters. This routine:
Example: IOINIT and logical unit preattachment:
CALL IOINIT ( .TRUE., .FALSE., .FALSE., 'FORT', .FALSE.) |
With the above example, suppose your program opened unit 7, as
follows:
OPEN( UNIT=07, FORM='FORMATTED' ) |
The FORTRAN runtime system looks in the environment for the FORT07 file, and connects it to unit 7.
Example: Attach external files ini1.inp and ini1.out to units 1 and 2:
demo$ TST01=ini1.inp demo$ TST02=ini1.out demo$ export TST01 TST02 |
demo% setenv TST01 ini1.inp demo% setenv TST02 ini1.out |
Example: Attach the files, ini1.inp and ini1.out,
to units 1 and 2:
demo% cp /opt/SUNWspro/SC4.2/src/ioinit.f . |
A direct-access file contains a number of records that are written to or read from by referring to the record number. Direct access is also called random access.
In direct access:Example: Direct access, unformatted:
OPEN( 2, FILE='data.db', ACCESS='DIRECT', RECL=20, & FORM='UNFORMATTED', ERR=90 ) READ( 2, REC=13, ERR=30 ) X, Y READ( 2 ' 13, ERR=30 ) X, Y ! |
Example: Direct access, formatted:
OPEN( 2, FILE='inven.db', ACCESS='DIRECT', RECL=20, & FORM='FORMATTED', ERR=90 ) READ( 2, FMT='(I10,F10.3)', REC=13, ERR=30 ) A, B |
An internal file is a character-string object, such as a constant, variable, substring, array, element of an array, or field of a structured record--all of type character. For a variable or substring, there is only a single record in the file but for an array; each array element is a record.
On internal files, the FORTRAN Standard includes only sequential formatted I/O. (I/O is not a precise term to use here, but internal files are dealt with using READ and WRITE statements.) Internal files are used by giving the name of the character object in place of the unit number. The first read from a sequential-access internal file always starts at the beginning of the internal file; similarly for a write.
Example: Sequential, formatted reads:CHARACTER X*80 READ( 5, '(A)' ) X READ( X, '(I3,I4)' ) N1, N2 |
The above code reads a print-line image into X, and then reads two integers from X.
f77
extends direct I/O to internal files.In formatted I/O:
In general, a formatted read statement does the following:
Example: Formatted read:
READ( 6, 10 ) A, B 10 FORMAT( F8.3, F6.2 ) |
In general, a formatted write statement does the following:
Example: Formatted write:
REAL A / 1.0 /, B / 9.0 / WRITE( 6, 10 ) A, B 10 FORMAT( F8.3, F6.2 ) |
The definitions for the parameters, w, m, d, and e are:
You can write field descriptors A, D, E, F, G, I, L, O, or Z without the w, d,
or e field indicators. If these are not
unspecified, the appropriate defaults are used based on the data type of the I/O list
element. See
Typical format field descriptor forms that use w, d, or e include:
Aw, Iw, Lw, Ow, Zw, Dw.d, Ew.d, Gw.d, Ew.dEe, Gw.dEe
Example: With the default w=7 for INTEGER*2, and since 161 decimal = A1 hex:
INTEGER*2 M M = 161 WRITE ( *, 8 ) M 8 FORMAT ( Z ) END |
This example produces the following output:
demo% f77 def1.f def1.f: MAIN: demo% a.out
demo% |
The defaults for w, d, and e are summarized
in the following table.
The apostrophe edit specifier is in the form of a character constant. It causes characters to be written from the enclosed characters of the edit specifier itself, including blanks. An apostrophe edit specifier must not be used on input. The width of the field is the number of characters contained in, but not including, the delimiting apostrophes. Within the field, two consecutive apostrophes with no intervening blanks are counted as a single apostrophe. You can use quotes in a similar way.
Example: apos.f, apostrophe edit (two equivalent ways):WRITE( *, 1 ) 1 FORMAT( 'This is an apostrophe ''.') WRITE( *, 2 ) 2 FORMAT( "This is an apostrophe '.") END |
The above program writes this message twice: This is an apostrophe '.
The B, BN, and BZ edit specifiers control interpretation of imbedded and trailing blanks for numeric input.
The following blank specifiers are available:Without any specific blank specifiers in the format, nonleading blanks in numeric input fields are normally interpreted as zeros or ignored, depending on the value of the BLANK= suboption of OPEN currently in effect for the unit. The default value for that suboption is ignore, so if you use defaults for both BN/BZ/B and BLANK=, you get ignore.
Example: Read and print the same data once with BZ and once with BN:Note these rules for blank control:
You use $, the space, 0, and 1 for carriage control.
The special edit descriptor $ suppresses the carriage return.
* dol1.f The $ edit descriptor with space WRITE ( *, 2 ) 2 FORMAT (' Enter the node number: ', $ ) READ ( *, * ) NODENUM END |
The above code produces a displayed prompt and user input response, such
as:
Enter the node number: 82 |
The following first-character slew controls and actions are provided:
Table 5-4 Carriage Control with Blank, 0, 1, and + |
|
Character |
Vertical spacing before printing |
Blank 0 1 + |
One line Two lines To first line of next page No advance (stdout only, not files) |
Space, 0, 1, and + work for stdout if piped through asa.
Example: First-character formatting, standard output piped through asa:
The program, slew1.f produces file, slew1.out, as
printed by lpr:
bcd efg hij |
klmnop |
The results are different on a screen; the tabbing puts in spaces:
demo% cat slew1.out bcd efg hij |
nop demo% |
The space, 0, and 1, and + work for a file opened with:
Example: First-character formatting, file output:
The A specifier is used for character type data items. The general form is:
A [ w ] |
On input, character data is stored in the corresponding list item.
On output, the corresponding list item is displayed as character data.
Each of the following examples read into a size n variable (CHARACTER*n),
for various values of n, for instance, for n = 9.
CHARACTER C*9 READ '( A7 )', C |
The various values of n, in CHARACTER C*n
are:
Size n |
9 |
7 |
4 |
1 |
Data | Node![]() |
Node![]() |
Node![]() |
Node![]() |
Format | A7 | A7 | A7 | A7 |
Memory | Node![]() ![]() ![]() |
Node![]() |
e![]() |
d |
Example: Output strings of 3, 5, and 7 characters, each in a 5
character field:
PRINT 1, 'The', 'whole', 'shebang' 1 FORMAT( A5 / A5 / A5 ) END |
whole sheba |
The maximum characters in noncharacter types are summarized in the
following table.
For example, these two formats are equivalent:
10 FORMAT( 8H Code = , A6 ) 20 FORMAT( ' Code = ', A6 ) |
In f77, commas between edit descriptors are generally
optional:
10 FORMAT( 5H flex 4Hible ) |
For compatibility with older programs, f77 also allows READs into
Hollerith edit descriptors.
demo% cat hol1.f WRITE( *, 1 ) 1 FORMAT( 6Holder ) READ( *, 1 ) WRITE( *, 1 ) END demo% f77 hol1.f hol1.f: MAIN demo% a.out older newer newer demo% |
CHARACTER F*18 / '(A8)' / READ(*,F) ! ... |
Obviously, there are better ways to read into the actual format.
The I specifier is used for decimal integer data items. The general form is:
I [w [ . m ] ] |
On input, an I w.m edit specifier is treated identically to an I w edit specifier.
The output field for the I w edit specifier consists of:
An integer constant always has at least one digit.
The output field for the I w.m edit specifier is the same as for the I w edit specifier, except that the unsigned integer constant consists of at least m digits, and, if necessary, has leading zeros. The value of m must not exceed the value of w. If m is zero, and the value of the item is zero, the output field consists of only blank characters, regardless of the sign control in effect. Example: int1.f, integer input:CHARACTER LINE*8 / '12345678' / READ( LINE, '(I2, I3, I2 )') I, J, K PRINT *, I, J, K END |
12 345 67 |
Example: int2.f, integer output:
N = 1234 PRINT 1, N, N, N, N 1 FORMAT( I6 / I4 / I2 / I6.5 ) END |
1234 1234 ** 01234 |
The L specifier is used for logical data items. The general form is:
L w |
Example: log1.f, logical output:
LOGICAL A*1 /.TRUE./, B*2 /.TRUE./, C*4 /.FALSE./ PRINT '( L1 / L2 / L4 )', A, B, C END |
T
|
Example: log2.f, logical input:
LOGICAL*4 A 1 READ '(L8)', A PRINT *, A GO TO 1 END |
The program above accepts any of the following as valid input data:
t true T TRUE .t .t. .T .T. .TRUE. TooTrue f false F FALSE .f .F .F. .FALSE. Flakey |
The O and Z field descriptors for a FORMAT statement are for octal and hexadecimal
integers, respectively, but they can be used with any data type.
Ow[.m] |
Zw[.m] |
A READ, with the O or Z field descriptors in the FORMAT, reads in w characters as octal or hexadecimal, respectively, and assigns the value to the corresponding member of the I/O list.
Example: Octal input, the external data field is:654321 |
The program that does the input is:
READ ( *, 2 ) M 2 FORMAT ( O6 ) |
The general rules for octal and hex input are:
A WRITE, with the O or Z field descriptors in the FORMAT, writes out values as octal or hexadecimal integers, respectively. It writes to a field that is w characters wide, right-justified.
Example: Hex output:M = 161 WRITE ( *, 8 ) M 8 FORMAT ( Z3 ) END |
The program above displays A1 (161 decimal = A1 hex):
|
Further examples are included in the following table.
The general rules for octal and hex output are:
For horizontal positioning along the print line, f77 supports the forms:
TRn, TLn, Tn, nT, T where n is a strictly positive integer. The format specifier T can appear by itself, or be preceded or followed by a positive nonzero number.This tab reads from the nth column or writes to the nth column.
This tab reads from the nth column to the left or writes to the nth column to the left.
This tab reads from the nth column to the right or writes to the nth column to the right.
This tab tabs to the nth tab stop for both read and write. If n is omitted, this tab uses n = 1 and tabs to the next tab stop.
This tab tabs to the next tab stop for both read and write. It is the same as the nTL with n omitted; it tabs to the next tab stop.
The rules and Restrictions for tabbing are:The nX edit specifier indicates that the transmission of the next character to or from a record is to occur at the position n characters forward from the current position.
On input, the nX edit specifier advances the record pointer by n positions, skipping n characters. A position beyond the last character of the record can be specified if no characters are transmitted from such positions. On output, the nX specifier writes n blanks. The n defaults to 1. Example: Input, Tn (absolute tabs):demo% cat rtab.f CHARACTER C*2, S*2 OPEN( 1, FILE='mytab.data') DO I = 1, 2 READ( 1, 2 ) C, S 2 FORMAT( T5, A2, T1, A2 ) PRINT *, C, S END DO END demo% |
demo% cat mytab.data defguvwx 12345678 demo% |
demo% a.out uvde 5612 demo% |
The above example first reads columns 5 and 6, then columns 1 and 2.
Example: Output Tn (absolute tabs); this program writes an
output file:
demo% cat otab.f CHARACTER C*20 / "12345678901234567890" / OPEN( 1, FILE='mytab.rep') WRITE( 1, 2 ) C, ":", ":" 2 FORMAT( A20, T10, A1, T20, A1 ) END demo% |
demo% cat mytab.rep 123456789:123456789: demo% |
The above example writes 20 characters, then changes columns 10 and 20.
Example: Input, TRn and TL n (relative tabs)--the program reads:
demo% cat rtabi.f CHARACTER C, S, T OPEN( 1, FILE='mytab.data') DO I = 1, 2 READ( 1, 2 ) C, S, T 2 FORMAT( A1, TR5, A1, TL4, A1 ) PRINT *, C, S, T END DO END demo% |
demo% cat mytab.data defguvwx 12345678 demo% |
demo% a.out dwg 174 demo% |
The above example reads column 1, then tabs right 5 to column 7, then tabs left 4 to column 4.
Example: Output TR n and TL n (relative
tabs)--this program writes an output file:
demo% cat rtabo.f CHARACTER C*20 / "12345678901234567890" / OPEN( 1, FILE='rtabo.rep') WRITE( 1, 2 ) C, ":", ":" 2 FORMAT( A20, TL11, A1, TR9, A1 ) END demo% |
The run shows nothing, but you can list the mytab.rep output file:
demo% cat rtabo.rep 123456789:123456789: demo% |
The above program writes 20 characters, tabs left 11 to column 10, then tabs right 9 to column 20.
The quotes edit specifier is in the form of a character constant. It causes characters to be written from the enclosed characters
of the edit specifier itself, including blanks. A quotes edit specifier must not be used
on input.
WRITE( *, 1 ) 1 FORMAT( 'This is a quote ".' ) WRITE( *, 2 ) 2 FORMAT( "This is a quote ""." ) END |
This program writes this message twice: This is a quote ".
The format specifier is R or nR, where 2 n
36.
If n is omitted, the default decimal radix is restored.
demo% cat radix.f integer i / 110 / write( *, 1 ) i 1 format( SU, 16r, I10.8 ) end demo% f77 -silent radix.f demo% a.out
demo% |
SU is described in the section, "Sign Editing (SU, SP, SS, S)."
The D, E, F, and G specifiers are for decimal real data items.
The D specifier is for the exponential form of decimal double-precision items. The
general form is:
D [ w [ .d ] ] |
Example: Real input with D editing in the program, Dinp.f:
CHARACTER LINE*24 / '12345678 23.5678 .345678' / READ( LINE, '( D8.3, D8.3, D8.3 )') R, S, T PRINT '( D10.3, D11.4, D13.6 )', R, S, T END |
0.123D+05 0.2357D+02 0.345678D+00 |
Example: Real output with D editing in the program Dout.f:
R = 1234.678 PRINT 1, R, R, R 1 FORMAT( D9.3 / D8.4 / D13.4 ) END |
0.123D+04 ********
|
The E specifier is for the exponential form of decimal real data items. The
general form is:
E [ w [ .d ] [ Ee ] ] |
w indicates that the field to be edited occupies w positions.
e indicates the number of digits in the exponent field. The default is 2.
For the form Ew.dEe, if | exponent | ( 10e ) - 1, then
the exponent has the form ±nnn.
n is any digit.
The sign in the exponent is required. w need not allow for a minus sign, but must allow for a zero, the decimal point, and d digits to the right of the decimal point, and an exponent. Therefore, for nonnegative numbers, wCHARACTER L*40/'1234567E2 1234.67E-3 12.4567 '/ READ( L, '( E9.3, E12.3, E12.6 )') R, S, T PRINT '( E15.6, E15.6, E15.7 )', R, S, T END |
|
Example: Real output with E editing in the program Eout.f:
R = 1234.678 PRINT 1, R, R, R 1 FORMAT( E9.3 / E8.4 / E13.4 ) END |
0.123E+04 ********
|
Example: Real output with Ew.dEe
editing in the program EwdEe.f:
REAL X / 0.000789 / WRITE(*,'( E13.3)') X WRITE(*,'( E13.3E4)') X WRITE(*,'( E13.3E5)') X END |
|
The F specifier is for decimal real data items. The general form is:
F [ w [ .d ] ] |
The Fw and Fw.d edit specifiers indicate that the field to be edited occupies w positions.
Example: Real input with F editing in the program Finp.f:
CHARACTER LINE*24 / '12345678 23.5678 .345678' / READ( LINE, '( F8.3, F8.3, F8.3 )') R, S, T PRINT '( F9.3, F9.4, F9.6 )', R, S, T END |
12345.678DD23.5678D0.345678 |
Example: Real output with F editing in the program Fout.f:
R = 1234.678 PRINT 1, R, R, R 1 FORMAT( F9.3 / F8.4 / F13.4 ) END |
********
|
The G specifier is for decimal real data items. The general form is:
G [ w [ .d ] ] | |
or: | |
G w.d E e |
The D, E, F, and G edit specifiers interpret data in the same way.
Range |
Form |
0.1 ![]() 1.0 ... 10(d-2) 10(d-1) |
F(w-4).d, n(![]() F(w-4).(d-1), n( ... F(w-4).1, n( F(w-4).0, n( |
If you are entering numeric data that is controlled by a fixed-column format, then you can use commas to override any exacting column restrictions.
Example: Format:(I10, F20.10, I4) |
Using the above format reads the following record correctly:
-345,.05e-3,12 |
The Q edit descriptor gets the length of an input record or the remaining portion of it
that is unread. It gets the number of characters remaining
to be read from the current record.
Example: Get length of input record; put the Q descriptor
first:
Several restrictions on the Q edit descriptor apply:
The P edit descriptor scales real input values by a power of 10. It also gives you more control over the significant digit displayed for output values.
The general form is:[ k ] P | |
k | Integer constant, with an optional sign |
k is called the scale factor, and the default value is zero.
Example: I/O statements with scale factors:
READ ( 1, '( 3P E8.2 )' ) X WRITE ( 1, '( 1P E8.2 )' ) X |
The scale factor is reset to zero at the start of execution of each I/O statement. The scale factor can have an effect on D, E, F, and G edit descriptors.
On input, any external datum that does not have an exponent field is divided by 10k before it is stored internally.
Input examples: Showing data, scale factors, and resulting value stored:Data | 18.63 | 18.63 | 18.63E2 | 18.63 |
Format | E8.2 | 3P E8.2 | 3P E8.2 | -3P E8.2 |
Memory | 18.63 | .01863 | 18.63E2 | 18630. |
On output, with D, and E descriptors, and with G descriptors if the E editing is required, the internal item gets its basic real constant part multiplied by 10k, and the exponent is reduced by k before it is written out.
On output with the F descriptor and with G descriptors, if the F editing is sufficient, the internal item gets its basic real constant part multiplied by 10k before it is written out. Output Examples: Showing value stored, scale factors, and resulting output:Memory | 290.0 | 290.0 | 290.0 | 290.0 |
Format | 2P E9.3 | 1P E9.3 | -1P E9.3 | F9.3 |
Display | 29.00E+01 | 2.900E+02 | 0.029E+04 | 0.290E+03 |
The SU, SP, and S edit descriptors control leading signs for output. For normal output, without any specific sign specifiers, if a value is negative, a minus sign is printed in the first position to the left of the leftmost digit; if the value is positive, printing a plus sign depends on the implementation, but f77 omits the plus sign.
The following sign specifiers are available:For example, the unsigned specifier can be used with the radix specifier to format a
hexadecimal dump, as follows:
2000 FORMAT( SU, 16R, 8I10.8 ) |
The rules and restrictions for sign control are:
The slash ( / ) edit specifier indicates the end of data transfer on the current record.
On input, any remaining portion of the current record is skipped, and the file is positioned at the beginning of the next record. Two successive slashes (//) skip a whole record.
On output, an end-of-record is written, and a new record is started. Two successive slashes (//) produce a record of no characters. If the file is an internal file, that record is filled with blanks.Each slash increases the record number by one, and the file is positioned at the start of the record with that record number.
On output, two successive slashes (//) produce a record of no characters, and that record is filled with blanks.The colon (:) edit descriptor allows for conditional termination of the format. If the I/O list is exhausted before the format, then the format terminates at the colon.
Example: Termination control:* col1.f The colon (:) edit descriptor DATA INIT / 3 /, LAST / 8 / WRITE ( *, 2 ) INIT WRITE ( *, 2 ) INIT, LAST 2 FORMAT ( 1X 'INIT = ', I2, :, 3X, 'LAST = ', I2 ) END |
The above program produces output like the following
INIT = 3 INIT = 3 LAST = 8 |
Without the colon, the output is more like this:
INIT = 3 LAST = INIT = 3 LAST = 8 |
You can put the format specifier into an object that you can change during execution. Doing so improves flexibility. There is some increase in execution time because this kind of format specifier is parsed every time the I/O statement is executed. These are also called variable formats.
The object must be one of the following kinds:You must provide the delimiting left and right parentheses, but not the word FORMAT, and not a statement number.
You must declare the object so that it is big enough to hold the entire format. For instance, '(8X,12I)' does not fit in an INTEGER*4 or a CHARACTER*4 object. Examples: Runtime formats in character expressions and integer arrays:In general, inside a FORMAT statement, any integer constant can be replaced by an
arbitrary expression.
1 FORMAT( 3F6.1 ) |
can be replaced by the variable N, as in:
1 FORMAT( 3F<N>.1 ) |
or by the slightly more complicated expression 2*N+M, as in:
1 FORMAT( 3F<2*N+M>.1 ) |
Similarly, the 3 or 1 can be replaced by any expression.
The single exception is the n in an nH... edit descriptor.
The rules and restrictions for variable format expressions are:
Unformatted I/O is used to transfer binary information to or from memory locations without changing its internal representation. Each execution of an unformatted I/O statement causes a single logical record to be read or written. Since internal representation varies with different architectures, unformatted I/O is limited in its portability.
You can use unformatted I/O to write data out temporarily, or to write data out quickly for subsequent input to another FORTRAN program running on a machine with the same architecture.Logical record length for unformatted, sequential files is determined by the number of bytes required by the items in the I/O list. The requirements of this form of I/O cause the external physical record size to be somewhat larger than the logical record size.
Example:WRITE( 8 ) A, B |
If your I/O lists are different lengths, you can OPEN the file with the RECL=1 option. This signals FORTRAN to use the I/O list to determine how many items to read or write.
For each read, you still must tell it the initial record to start at, in this case which byte, so you must know the size of each item.Example: Direct access--read the 3 records:
Example: Direct-access read, variable-length records, recl=1:
In the above example, after reading 3 integers (12 bytes), you start the next read at record 13.
List-directed I/O is a free-form I/O for sequential access devices. To get it, use an
asterisk as the format identifier, as in:
READ( 6, * ) A, B, C |
Note these rules for list-directed input:
4*(3.,2.) 2*, 4*'hello' |
List-directed output provides a quick and easy way to print output without fussing with format details. If you need exact formats, use formatted I/O. A suitable format is chosen for each item, and where a conflict exists between complete accuracy and simple output form, the simple form is chosen.
Note these rules for list-directed output:demo% cat lis5.f READ ( 5, * ) X WRITE( 6, * ) X, ' beauty' WRITE( 6, 1 ) X 1 FORMAT( 1X, F13.8, ' truth' ) END demo% f77 lis5.f lis5.f: MAIN: demo% a.out 1.4 1.40000000 beauty 1.39999998 truth demo% |
Also note:
Example: List-directed I/O and backslash-n, with and without -xl:
demo% cat f77 bslash.f CHARACTER S*8 / '12\n3' / PRINT *, S END demo% |
Without -xl, \n prints as a carriage return:
demo% f77 -silent bslash.f demo% a.out 12 3 demo% |
With -xl, \n prints as a character string:
demo% f77 -xl -silent bslash.f demo% a.out 12\n3 demo% |
COMPLEX*32
and REAL*16
are SPARC and
PowerPC only.
f77
list-directed I/O allows reading of a string not enclosed in quotes.CHARACTER C*6, S*8 READ *, I, C, N, S PRINT *, I, C, N, S END |
The above program, unquoted.f, reads and displays as follows:
demo% a.out 23 label 82 locked 23label 82locked demo% |
f77
extends list-directed I/O to allow internal I/O.NAMELIST
I/O produces format-free input or output of whole groups of variables, or input of selected items in a group of variables.The syntax of the NAMELIST statement is:
NAMELIST /group-name/namelist[[,]/group-name/namelist]... | |
group-name | Identifier |
namelist | List of variables or arrays, separated by commas |
CHARACTER*18 SAMPLE LOGICAL*4 NEW REAL*4 DELTA NAMELIST /CASE/ SAMPLE, NEW, DELTA |
A variable or array can be listed in more than one NAMELIST group.
group name
can appear in only the NAMELIST, READ, or WRITE statements, and must be unique for the program. list cannot include constants, array elements, dummy assumed-size arrays, structures, substrings, records, record fields, pointers, or pointer-based variables. Example: A variable in two NAMELIST groups:REAL ARRAY(4,4) CHARACTER*18 SAMPLE LOGICAL*4 NEW REAL*4 DELTA NAMELIST /CASE/ SAMPLE, NEW, DELTA NAMELIST /GRID/ ARRAY, DELTA |
In the above example, DELTA is in the group CASE and in the group GRID.
NAMELIST
output uses a special form of WRITE statement, which makes a report that shows the group name. For each variable of the group, it shows the name and current value in memory. It formats each value according to the type of each variable, and writes the report so that NAMELIST input can read it. The syntax of NAMELIST WRITE is:WRITE ( extu, namelist-specifier [, iostat] [, err]) |
where namelist-specifier has the form:
[NML=]group-name |
and group-name has been previously defined in a NAMELIST statement.
The WRITE can have the form of the following example:
WRITE ( UNIT=6, NML=CASE ) |
The NAMELIST input statement reads the next external record, skipping over column one, and looking for the symbol $ in column two or beyond, followed by the group name specified in the READ statement.
If the $group-name is not found, the input records are read until end of file. The records are input and values assigned by matching names in the data with names in the group, using the data types of the variables in the group. Variables in the group that are not found in the input data are unaltered. The syntax of NAMELIST READ is:READ ( extu, namelist-specifier [, iostat] [, err] [, end]) |
where namelist-specifier has the form:
[NML=]group-name |
and group-name has been previously defined in a NAMELIST statement.
CHARACTER*14 SAMPLE LOGICAL*4 NEW REAL*4 DELTA, MAT(2,2) NAMELIST /CASE/ SAMPLE, NEW, DELTA, MAT READ ( 1, CASE ) |
The READ can have the form of the following example:
READ ( UNIT=1, NML=CASE ) |
The first record of NAMELIST input data has the special symbol $
(dollar sign) in column two or beyond, followed by the NAMELIST group name.
This is followed by a series of assignment statements, starting in or after column two, on
the same or subsequent records, each assigning a value to a variable (or one or more
values to array elements) of the specified group. The input data is terminated with
another $ in or after column two, as in the pattern:
![]() |
The input data assignment statements must be in one of the following
forms:
variable=value |
array=value1[, value2,]... |
array(subscript)=value1[, value2,]... |
array(subscript,subscript)=value1[, value2,]... |
variable=character constant |
variable(index:index)=character constant |
The following is sample data to be read by the program segment
above:
|
|
The following syntax rules apply for input data to be read by NAMELIST:
|
A complex constant is a pair of real or integer constants separated by a comma and enclosed in parentheses. Spaces can occur only around the punctuation.
A logical constant is any form of true or false value, such as .TRUE. or .FALSE., or any value beginning with .T, .F, and so on. A null data item is denoted by two consecutive commas, and it means the corresponding array element or complex variable value is not to be changed. Null data item can be used with array elements or complex variables only. One null data item represents an entire complex constant; you cannot use it for either part of a complex constant. Example: NAMELIST input with some null data:* nam2.f Namelist input with consecutive commas REAL ARRAY(4,4) NAMELIST /GRID/ ARRAY WRITE ( *, * ) 'Input?' READ ( *, GRID ) WRITE ( *, GRID ) END |
|
This code loads 9s into row 1, skips 4 elements, and loads 8s into row 3 of ARRAY.
The forms r*c and r* can be used only with an array.
The form r*c stores r copies of the constant c into an array, where r is a nonzero, unsigned integer constant, and c is any constant. Example: NAMELIST with repeat-factor in data:* nam3.f Namelist "r*c" and "r* " REAL PSI(10) NAMELIST /GRID/ PSI WRITE ( *, * ) 'Input?' READ ( *, GRID ) WRITE ( *, GRID ) END |
|
Example: NAMELIST input with some skipped data.
The other input is:
|
If your program is doing NAMELIST input from the terminal, you can request the group name and NAMELIST names that it accepts.
To do so, enter a question mark (?) in column two and press Return. The group name and variable names are then displayed. The program then waits again for input. Example: Requesting names: