Fortran 77 Language Reference HomeContentsPreviousNextIndex


Chapter 5

Input and Output

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 Fortran Programming Guide.

Essential FORTRAN I/O Concepts

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.

Logical Units

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 setrlim(2) man page. 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 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 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.

I/O Errors

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.

General Restriction

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

Kinds of I/O

The kinds of I/O supported by f77 are: formatted, unformatted, binary, 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.

Combinations of I/O

I/O combinations on external files are:

Allowed Not Allowed
Sequential unformatted
Sequential formatted
Sequential list-directed
Sequential NAMELIST
Direct unformatted
Direct formatted
Binary sequential unformatted
Direct-access, list-directed I/O
Direct-access, NAMELIST I/O
NAMELIST I/O on internal files
Unformatted, internal I/O
Binary, direct-access Binary, formatted


The following table shows combinations of I/O form, access mode, and physical file types.

TABLE 5-1   Summary of f77 Input and Output  
Kind of I/O Access Mode:
Form File Type Sequential Direct
Formatted Internal The file is a character variable, substring, array, or array element. The file is a character array; each record is one array element.
External Only formatted records of same or variable length. Only formatted records, all the same length.
Unformatted Internal Not allowed. Not allowed.
External Contains only unformatted records. READ: Gets one logical record at a time. WRITE: Unfilled part of record is undefined.
Binary Internal Not allowed. Not allowed.
External Contains only unformatted raw binary data, no record marks. Not allowed.
List-directed Internal READ: Reads characters until EOF or I/O list is satisfied.

WRITE
: Writes records until list is satisfied.
Not allowed.
External Uses standard formats based on type of variable and size of element. Blanks or commas are separators. Any columns. Not allowed.
NAMELIST Internal Not allowed. Not allowed.
External READ: Reads records until it finds $groupname in columns 2-80. Then reads records searching for names in that group, and stores data in those variables. Stops reading on $ or eof.

WRITE
: Writes records showing the group name and each variable name with value.
Not allowed.


Avoid list-directed internal writes. The number of lines and items per line varies with the values of items.

Printing Files

You get a print file by using the nonstandard FORM='PRINT' in OPEN.

	 OPEN ( ..., FORM='PRINT', ... )

This specifier works for sequential access files only.

Definition

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

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.

Special Uses of OPEN

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 between FORM='PRINT' and FORM='FORMATTED' does nothing but redefine that option.

These forms of the OPEN statement need not include the file name, and must not include a file name if UNIT refers to standard input, output, or standard error.

If you connect a unit with OPEN and do not use the file name parameter, then you get the default file name, fort.nn, where nn is the unit number. Therefore, to redefine the standard output as a print file, use:

	 OPEN( UNIT=6, FORM='PRINT')

Scratch Files

Scratch files are temporary files that normally disappears after execution is completed.

Example: Create a scratch file:

	 OPEN( UNIT=7, STATUS='SCRATCH' ) 

To prevent a temporary file from disappearing after execution is completed, you must execute a CLOSE statement with STATUS='KEEP'. KEEP is the default status for all other files.

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.

Changing I/O Initialization with IOINIT

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

For the above call, the FORTRAN runtime system looks in the environment for names of the form FORTnn, and then opens the corresponding logical unit for sequential formatted I/O.

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.

In general, names must be of the form PREFIXnn, where the particular PREFIX is specified in the call to IOINIT, and nn is the logical unit to be opened. Unit numbers less than 10 must include the leading 0. For details, see IOINIT(3F) and the Sun Fortran Library Reference.

Example: Attach external files ini1.inp and ini1.out to units 1 and 2:

In sh:

demo$ TST01=ini1.inp 
demo$ TST02=ini1.out 
demo$ export TST01 TST02 

In csh:

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% cat ini1.f 
	 CHARACTER PRFX*8 
	 LOGICAL CCTL, BZRO, APND, VRBOSE 
	 DATA CCTL, BZRO, APND, PRFX, VRBOSE 
& 	 	 /.TRUE., .FALSE., .FALSE., 'TST', .FALSE. / 
C 
	 CALL IOINIT( CCTL, BZRO, APND, PRFX, VRBOSE ) 
	 READ( 1, *) I, B, N 
	 WRITE( *, *) 'I = ', I, ' B = ', B, ' N = ', N 
	 WRITE( 2, *) I, B, N 
	 END 
demo% cat $TST01
 12 3.14159012 6
demo% f77 ini1.f
ini1.f: 
 MAIN: 
demo% a.out 
 I =   12 B =     3.14159 N =   6
demo% cat $TST02
   12    3.14159  6

IOINIT should prove adequate for most programs as written. However, it is written in FORTRAN so that it can serve as an example for similar user-supplied routines. A copy can be retrieved from:

/opt/SUNWspro/<release>/src/ioinit.f

The <release> path changes with each release of the compiler.

Direct Access

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:

Unformatted I/O

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	 	    !  Alternate form 

This code opens a file for direct-access, unformatted I/O, with a record length of 20 characters, then reads the thirteenth record as is.

Formatted I/O

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 

This code opens a file for direct-access, formatted I/O, with a record length of 20 characters, then reads the thirteenth record and converts it according to the (I10,F10.3) format.

Internal Files

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.

Sequential Formatted I/O

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.

Direct Access I/O

f77 extends direct I/O to internal files.

This is like direct I/O on external files, except that the number of records in the file cannot be changed. In this case, a record is a single element of an array of character strings.

Example: Direct access read of the third record of the internal file, LINE:

demo% cat intern.f 
	 CHARACTER LINE(3)*14 
	 DATA LINE(1) / ' 81 81 ' / 
	 DATA LINE(2) / ' 82 82 ' / 
	 DATA LINE(3) / ' 83 83 ' / 
	 READ ( LINE, FMT='(2I4)', REC=3 ) M, N 
	 PRINT *, M, N 
	 END 
demo% f77 -silent intern.f 
demo% a.out 
  83 83 
demo%

Formatted I/O

In formatted I/O:

Input Actions

In general, a formatted read statement does the following:

Example: Formatted read:

	 READ( 6, 10 ) A, B 
10	 FORMAT( F8.3, F6.2 ) 

Output Actions

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 ) 

For formatted write statements, the logical record length is determined by the format statement that interacts with the list of input or output variables (I/O list) at execution time.

For formatted write statements, if the external representation of a datum is too large for the field width specified, the specified field is filled with asterisks (*).

For formatted read statements, if there are fewer items in the list than there are data fields, the extra fields are ignored.

Format Specifiers

TABLE 5-2   Format Specifiers
Purpose FORTRAN 77 f77 Extensions
Blank control
BN, BZ 
B 
Carriage control
/, space, 0, 1
$
Character edit
nH, Aw, 'aaa'
"aaa", A 
Floating-point edit
Dw.dEe, 
E
w.dEe,
F
w.dEe,
G
w.dEe
Ew.d.e, 
D
w.d.e,
G
w.d.e
Hexadecimal edit
Zw.m 
Integer edit
Iw.m
 
Logical edit
Lw
 
Octal edit
Ow.m 
Position control
nX, Tn, TLn, TRn
nT, T, X 
Radix control
nR, R 
Remaining characters
Q
Scale control
nP
P 
Sign control
S, SP, SS 
SU 
Terminate a format
:
Variable format expression
< e > 


Specifiers can be uppercase as well as lowercase characters in format statements and in all the alphabetic arguments to the I/O library routines.

w, m, d, e Parameters (As In Gw.dEe)

The definitions for the parameters, w, m, d, and e are:

Defaults for w, d, and e

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 left unspecified, the appropriate defaults are used based on the data type of the I/O list element. See TABLE 5-3.

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
a1
demo%

represents a blank character position. The defaults for w, d, and e are summarized in the following table.

TABLE 5-3   Default w, d, e Values in Format Field Descriptors 
Field Descriptor List Element w d e
I,O,Z BYTE 7 - -
I,O,Z INTEGER*2, LOGICAL*2 7 - -
I,O,Z INTEGER*4, LOGICAL*4 12 - -
O,Z REAL*4 12 - -
O,Z REAL*8 23 - -
O,Z REAL*16, COMPLEX*32 44 - -
L LOGICAL 2 - -
F,E,D,G REAL, COMPLEX*8 15 7 2
F,E,D,G REAL*8, COMPLEX*16 25 16 2
F,E,D,G REAL*16, COMPLEX*32 42 33 3
A LOGICAL*1 1 - -
A LOGICAL*2, INTEGER*2 2 - -
A LOGICAL*4, INTEGER*4 4 - -
A REAL*4, COMPLEX*8 4 - -
A REAL*8, COMPLEX*16 8 - -
A REAL*16, COMPLEX*32 16 - -
A CHARACTER*n n - -


For complex items, the value for w is for each real component. The default for the A descriptor with character data is the declared length of the corresponding I/O list element. REAL*16 and COMPLEX*32 are SPARC only.

Apostrophe Editing ('aaa')

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

Blank Editing (B,BN,BZ)

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:

demo% cat bz1.f 
*	 	 	 	  12341234 
	 CHARACTER LINE*18 / ' 82 82 ' / 
	 READ ( LINE, '( I4, BZ, I4 ) ') M, N 
	 PRINT *, M, N 
	 READ ( LINE, '( I4, BN, I4 ) ') M, N 
	 PRINT *, M, N 
	 END 
demo% f77 -silent  bz1.f 
demo% a.out 
  82 8200 
  82 82 
demo%

Note these rules for blank control:

Carriage Control ($, space, 0,1)

Use edit descriptor $, and space, 0, or 1 for carriage control.

Dollar $

The special edit descriptor $ suppresses the carriage return.

The action does not depend on the first character of the format. It is used typically for console prompts. For instance, you can use this descriptor to make a typed response follow the output prompt on the same line. This edit descriptor is constrained by the same rules as the colon (:).

Example: The $ carriage control:

* 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 first character of the format is printed out, in this case, a blank. For an input statement, the $ descriptor is ignored.

Space, 0, 1, and +

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
(space)
0
1
+
One line
Two lines
To first line of next page
No advance (stdout only, not files)


If the first character of the format is not space, 0, 1, or +, then it is treated as a space, and it is not printed.

The behavior of the slew control character + is: if the character in the first column is +, it is replaced by a control sequence that causes printing to return to the first column of the previous line, where the rest of the input line is printed.

Space, 0, 1, and + work for stdout if piped through asa.

Example: First-character formatting, standard output piped through asa:

demo% cat slew1.f
	 WRITE( *, '("abcd")') 
	 WRITE( *, '(" efg")')  The blank single spaces
	 WRITE( *, '("0hij")')  The "0" double spaces
	 WRITE( *, '("1klm")')  The "1" starts this on a new page
	 WRITE( *, '("+", T5, "nop")')  The "+" starts this at col 1 of latest line
	 END
demo% f77 -silent slew1.f
demo% a.out | asa | lpr
demo%

The program, slew1.f produces file, slew1.out, as printed by lpr:

 bcd
 efg
 
 hij
 klmnop               This starts on a new page.  The + of +nop is obeyed.


The results are different on a screen; the tabbing puts in spaces:

 demo% cat slew1.out
 bcd
 efg
 
 hij
    nop       This starts on a new page. The + of +nop is obeyed.
 demo% 


See asa(1).

The space, 0, and 1, and + work for a file opened with:

Example: First-character formatting, file output:

demo% cat slew2.f
	 OPEN( 1,FILE='slew.out',FORM='PRINT' ) 
	 WRITE( 1, '("abcd")') 
	 WRITE( 1, '("efg")') 
	 WRITE( 1, '("0hij")') 
	 WRITE( 1, '("1klm")') 
	 WRITE( 1, '("+", T5, "nop")') 
	 CLOSE( 1, STATUS='KEEP') 
	 END
demo% f77 -silent slew2.f
demo% a.out

The program, slew2.f, produces the file, slew2.out, that is equal to the file, slew1.out, in the example above.

Slew control codes '0', '1', and '+' in column one are in the output file as '\n', '\f', and '\r', respectively.

Character Editing (A)

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.

If w is omitted, then:

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 NodeId NodeId NodeId NodeId
Format A7 A7 A7 A7
Memory NodeId NodeId eId d


indicates a blank space.

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 

The above program displays:

The
whole
sheba

The maximum characters in noncharacter types are summarized in the following table.

TABLE 5-5   Maximum Characters in Noncharacter Type Hollerith (nHaaa)
Type of List Item Maximum Number of Characters
BYTE
LOGICAL*1
LOGICAL*2
LOGICAL*4
LOGICAL*8
INTEGER*2
INTEGER*4
INTEGER*8
REAL
REAL*4
REAL*8
REAL*16 (SPARC only)
DOUBLE PRECISION
COMPLEX
COMPLEX*8
COMPLEX*16
COMPLEX*32 (SPARC only)
DOUBLE COMPLEX
1
1
2
4
8
2
4
8
4
4
8
16
8
8
8
16
32
16


In f77, you can use Hollerith constants wherever a character constant can be used in FORMAT statements, assignment statements, and DATA statements. These constants are not recommended. FORTRAN does not have these old Hollerith (nH) notations, although the FORTRAN Standard recommends implementing the Hollerith feature to improve compatibility with old programs. But such constants cannot be used as input data elements in list-directed or NAMELIST input.

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 ) 

Reading Into Hollerith Edit Descriptors

For compatibility with older programs, f77 also allows READs into Hollerith edit descriptors.

Example: Read into hollerith edit descriptor--no list in the READ statement:

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%

In the above code, if the format is a runtime format (variable format), then the reading into the actual format does not work, and the format remains unchanged. Hence, the following program fails:

	 CHARACTER F*18 / '(A8)' / 
	 READ(*,F)	 	 	 !  Does not work.
	 ... 

Obviously, there are better ways to read into the actual format.

Integer Editing (I)

The I specifier is used for decimal integer data items. The general form is:

I[w[.m]] 

The Iw and Iw.m edit specifiers indicate that the field to be edited occupies w positions. The specified input/output list item must be of type integer. On input, the specified list item becomes defined with an integer datum. On output, the specified list item must be defined as an integer datum.

On input, an Iw.m edit specifier is treated identically to an Iw edit specifier.

The output field for the Iw edit specifier consists of:

An integer constant always has at least one digit.

The output field for the Iw.m edit specifier is the same as for the Iw 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 

The program above displays:

     12 345 67

Example: int2.f, integer output:

	 N = 1234 
	 PRINT 1, N, N, N, N 
1	 FORMAT( I6 / I4 / I2 / I6.5 ) 
	 END 

The above program displays:

  1234 
1234 
** 
01234 

Logical Editing (L)

The L specifier is used for logical data items. The general form is:

 Lw

The Lw edit specifier indicates that the field occupies w positions. The specified input/output list item must be of type LOGICAL. On input, the list item becomes defined with a logical datum. On output, the specified list item must be defined as a logical datum.

The input field consists of optional blanks, optionally followed by a decimal point, followed by a T for true, or F for false. The T or F can be followed by additional characters in the field. The logical constants, .TRUE. and .FALSE.,are acceptable as input. The output field consists of w-1 blanks followed by a T for true, or F for false.

Example: log1.f, logical output:

	 LOGICAL A*1 /.TRUE./, B*2 /.TRUE./, C*4 /.FALSE./ 
	 PRINT '( L1 / L2 / L4 )', A, B, C 
	 END 

The program above displays:

T 
T 
F 

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 

Octal and Hexadecimal Editing (O, Z)

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.

The general form is:

  Ow[.m]
  Zw[.m]


where w is the number of characters in the external field. For output, m, if specified, determines the total number of digits in the external field; that is, if there are fewer than m nonzero digits, the field is zero-filled on the left to a total of m digits. m has no effect on input.

Octal and Hex Input      

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 first digit in the example appears in input column 1.

The program that does the input is:

	 READ ( *, 2 ) M 
2	 FORMAT ( O6 ) 

The above data and program result in the octal value 654321 being loaded into the variable M. Further examples are included in the following table.

TABLE 5-6   Sample Octal/Hex Input Values
Format External Field Internal (Octal or Hex) Value
O4
O4
O3
1234
16234
97
1234
1623
Error: "9" not allowed
Z5
Z5
Z4
A23DE
A23DEF
95.AF2
A23DE
A23DE
Error: "." not allowed


The general rules for octal and hex input are:

Octal and Hex Output

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

A1 

The letter A appears in output column 2.

Further examples are included in the following table.

TABLE 5-7   Sample Octal/Hex Output Value
Format Internal (Decimal) Value External (Octal/Hex) Representation
O6
O2
O4.3
O4.4
O6
32767
14251
27
27
-32767
 77777 
**
033
0033
*****
Z4
Z3.3
Z6.4
Z5
32767
2708
2708
-32767
 7FFF 
A94
0A94
******


The general rules for octal and hex output are:

Positional Editing

For horizontal positioning along the print line, f77 supports the forms:

Tn, TLn, TRn, nT, nX

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.

Tn--Absolute Columns

This tab reads from the nth column or writes to the nth column. If n is missing it is treated as T1.

TLn--Relative Columns

This tab reads from the nth column to the left or writes to the nth column to the left. If n is missing it is treated as TL0 .

TRn--Relative Columns

This tab reads from the nth column to the right or writes to the nth column to the right. If n is missing it is treated as TR0 .

nT--Relative Tab Stop

This tab tabs to the next tab stop for both read and write. If n is omitted, this tab uses n = 1 and tabs to the next tab stop. (This edit specifier is not standard FORTRAN 77)

The rules and Restrictions for tabbing are:

nX--Positions

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%

The two-line data file is:

demo% cat mytab.data 
defguvwx 
12345678 
demo%

The run and the output are:

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%

The output file is:

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%

The two-line data file is:

demo% cat mytab.data 
defguvwx
12345678
demo%

The run and the output are:

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.

Quotes Editing ("aaa")

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.

The width of the field is the number of characters contained in, but not including, the delimiting quotes. Within the field, two consecutive quotes with no intervening blanks are counted as a single quote. You can use apostrophes in a similar way.

Example: quote.f (two equivalent ways):

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

Radix Control (R)

The format specifier is R or nR, where 2 n 36. If n is omitted, the default decimal radix is restored.

You can specify radixes other than 10 for formatted integer I/O conversion. The specifier is patterned after P, the scale factor for floating-point conversion. It remains in effect until another radix is specified or format interpretation is complete. The I/O item is treated as a 32-bit integer.

Example: Radix 16--the format for an unsigned, hex, integer, 10 places wide, zero-filled to 8 digits, is (su, 16r, I10.8), as in:

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 
 0000006E 
demo%

SU is described in Sign Editing (SU, SP, SS, S).

Editing REAL Data (D, E, F, G)

The D, E, F, and G specifiers are for decimal real data items.

D Editing

The D specifier is for the exponential form of decimal double-precision items. The general form is

D[w[.d]] 

:

The Dw and Dw.d edit specifiers indicate that the field to be edited occupies w positions. d indicates that the fractional part of the number (the part to the right of the decimal point) has d digits. However, if the input datum contains a decimal point, that decimal point overrides the d value.

On input, the specified list item becomes defined with a real datum. On output, the specified list item must be defined as a real datum.

In an output statement, the D edit descriptor does the same thing as the E edit descriptor, except that a D is used in place of an E. The output field for the Dw.d edit specifier has the width w. The value is right-justified in that field. The field consists of zero or more leading blanks followed by either a minus if the value is negative, or an optional plus, followed by the magnitude of the value of the list item rounded to d decimal digits.

w must allow for a minus sign, at least one digit to the left of the decimal point, the decimal point, and d digits to the right of the decimal point. Therefore, it must be the case that w d+3.

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 

The above program displays:

0.123D+05 0.2357D+02 0.345678D+00 

In the above example, the first input data item has no decimal point, so D8.3 determines the decimal point. The other input data items have decimal points, so those decimal points override the D edit descriptor as far as decimal points are concerned.

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

The above program displays:

0.123D+04 
******** 
0.1235D+04 

In the above example, the second printed line is asterisks because the D8.4 does not allow for the sign; in the third printed line the D13.4 results in three leading blanks.

E Editing

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.

d indicates that the fractional part of the number (the part to the right of the decimal point) has d digits. However, if the input datum contains a decimal point, that decimal point overrides the d value.

e indicates the number of digits in the exponent field. The default is 2.

The specified input/output list item must be of type real. On input, the specified list item becomes defined with a real datum. On output, the specified list item must be defined as a real datum.

The output field for the Ew.d edit specifier has the width w. The value is right-justified in that field. The field consists of zero or more leading blanks followed by either a minus if the value is negative, or an optional plus, followed by a zero, a decimal point, the magnitude of the value of the list item rounded to d decimal digits, and an exponent.

For the form Ew.d:

For the form Ew.dEe, if | exponent | ( 10e ) - 1, then the exponent has the form ±nnn.

For the form Dw.d:

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, w d+6; if e is present, then w d+e+4. For negative numbers, w d+7; if e is present, then w d+e+5.

Example: Real input with E editing in the program, Einp.f:

	 CHARACTER 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 

The above program displays:

0.123457E+060.123467E+010.1245670E+02 

In the above example, the first input data item has no decimal point, so E9.3 determines the decimal point. The other input data items have decimal points, so those decimal points override the D edit descriptor as far as decimal points are concerned.

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 

The above program displays:

0.123E+04 
******** 
0.1235E+04 

In the above example, E8.4 does not allow for the sign, so we get asterisks. Also, the extra wide field of the E13.4 results in three leading blanks.

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 above program displays:

0.789E-03
0.789E-0003
0.789E-00003

F Editing

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.

d indicates that the fractional part of the number (the part to the right of the decimal point) has d digits. However, if the input datum contains a decimal point, that decimal point overrides the d value.

The specified input/output list item must be of type real. On input, the specified list item becomes defined with a real datum. On output, the specified list item must be defined as a real datum.

The output field for the Fw.d edit specifier has the width w. The value is right-justified in that field. The field consists of zero or more leading blanks followed by either a minus if the value is negative, or an optional plus, followed by the magnitude of the value of the list item rounded to d decimal digits.

w must allow for a minus sign, at least one digit to the left of the decimal point, the decimal point, and d digits to the right of the decimal point. Therefore, it must be the case that w d+3.

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 

The program displays:

12345.678DD23.5678D0.345678

In the above example, the first input data item has no decimal point, so F8.3 determines the decimal point. The other input data items have decimal points, so those decimal points override the F edit descriptor as far as decimal points are concerned.

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 above program displays:

1234.678 
******** 
1234.6780

In the above example, F8.4 does not allow for the sign; F13.4 results in four leading blanks and one trailing zero.

G Editing

The G specifier is for decimal real data items. The general forms are

G[w[.d]]      or
Gw.dEe

:

The D, E, F, and G edit specifiers interpret data in the same way.

The representation for output by the G edit descriptor depends on the magnitude of the internal datum. In the following table, N is the magnitude of the internal datum.

Range Form
0.1 N < 1.0
1.0 N < 10.0
...
10(d-2) N < 10(d-1)
10(d-1) N < 10d
F(w-4).d
F(w-4).(d-1)
...
F(w-4).1
F(w-4).0


Commas in Formatted Input

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 I/O system is just being more lenient than described in the FORTRAN Standard. In general, when doing a formatted read of noncharacter variables, commas override field lengths. More precisely, for the Iw, Fw.d, Ew.d[Ee], and Gw.d input fields, the field ends when w characters have been scanned, or a comma has been scanned, whichever occurs first. If it is a comma, the field consists of the characters up to, but not including, the comma; the next field begins with the character following the comma.

Remaining Characters (Q)

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: From a real and a string, get: real, string length, and string:

demo% cat qed1.f 
* qed1.f Q edit descriptor (real & string) 
	 CHARACTER CVECT(80)*1 
	 OPEN ( UNIT=4, FILE='qed1.data' ) 
	 READ ( 4, 1 ) R, L, ( CVECT(I), I=1,L ) 
1 	 FORMAT ( F4.2, Q, 80 A1 ) 
	 WRITE ( *, 2 ) R, L, '"', (CVECT(I),I=1,L), '"' 
2 	 FORMAT ( 1X, F7.2, 1X, I2, 1X, 80A1 ) 
	 END 
demo% cat qed1.data 
8.10qwerty 
demo% f77 qed1.f -o qed1 
qed1.f: 
 MAIN: 
demo% qed1 
   8.10 6 "qwerty" 
demo%

The above program reads a field into the variable R, then reads the number of characters remaining after that field into L, then reads L characters into CVECT. Q as the nth edit descriptor matches with L as the nth element in the READ list.

Example: Get length of input record; put the Q descriptor first:

demo% cat qed2.f 
	 CHARACTER CVECT(80)*1 
	 OPEN ( UNIT=4, FILE='qed2.data' ) 
	 READ ( 4, 1 ) L, ( CVECT(I), I=1,L ) 
1	 FORMAT ( Q, 80A1 ) 
	 WRITE ( *, 2 ) L, '"', (CVECT(I),I=1,L), '"' 
2	 FORMAT ( 1X, I2, 1X, 80A1 ) 
	 END 
demo% cat qed2.data 
qwerty 
demo% f77 qed2.f -o qed2 
qed2.f: 
 MAIN: 
demo% qed2 
  6 "qwerty" 
demo%

The above example gets the length of the input record. With the whole input string and its length, you can then parse it yourself.

Several restrictions on the Q edit descriptor apply:

Scale Factor (P)

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

Parameter Description
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 

P by itself is equivalent to 0P. It resets the scale factor to the default value 0P. Just P by itself is nonstandard.

Scope

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.

Input

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.


Output

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


Sign Editing (SU, SP, SS, S)

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:

Slash Editing (/)

The slash ( / ) edit specifier indicates the end of data transfer on the current record.

Sequential Access

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.

Direct Access

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.

Termination Control (:)

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 

Runtime Formats

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

demo% cat runtim.f 
	 CHARACTER CS*8 
	 CHARACTER CA(1:7)*1 /'(','1','X',',','I','2',')'/ 
	 CHARACTER S(1:7)*6 
	 INTEGER*4 IA(2) 
	 STRUCTURE / STR / 
	 	 CHARACTER*4 A 
	 	 INTEGER*4 K 
	 END STRUCTURE 
	 CHARACTER*8 LEFT, RIGHT 
	 RECORD /STR/ R 
	 N = 9 
	 CS = '(I8)' 
	 WRITE( *, CS ) N 	 	 ! Character Scalar 
	 CA(2) = '6' 
	 WRITE( *, CA ) N 	 ! Character Array 
	 S(2) = '(I8)' 
	 WRITE( *, S(2) ) N 	 ! Element of Character Array 
	 IA(1) = '(I8)' 
	 WRITE(*, IA ) N 	 ! Integer Array 
	 R.A = '(I8)' 
	 WRITE( *, R.A ) N 	 ! Field Of Record 
	 LEFT = '(I' 
	 RIGHT = '8)' 
	 WRITE(*, LEFT // RIGHT ) N ! Concatenate 
	 END 
demo% f77 -silent runtim.f 
demo% a.out 
       9 
       9 
       9 
       9 
       9 
       9 
demo%

:

Variable Format Expressions (<e>)

In general, inside a FORMAT statement, any integer constant can be replaced by an arbitrary expression.

The expression itself must be enclosed in angle brackets.

For example, the 6 in:

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

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.

Sequential Access I/O

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 

The FORTRAN runtime system embeds the record boundaries in the data by inserting an INTEGER*4 byte count at the beginning and end of each unformatted sequential record during an unformatted sequential WRITE. The trailing byte count enables BACKSPACE to operate on records. The result is that FORTRAN programs can use an unformatted sequential READ only on data that was written by an unformatted sequential WRITE operation. Any attempt to read such a record as formatted would have unpredictable results.

Here are some guidelines:

Direct Access I/O

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.

A simple example follows.

Example: Direct access--create 3 records with 2 integers each:

demo% cat Direct1.f
	 integer u/4/, v /5/, w /6/, x /7/, y /8/, z /9/
	 open( 1, access='DIRECT', recl=8 )
	 write( 1, rec=1 ) u, v
	 write( 1, rec=2 ) w, x
	 write( 1, rec=3 ) y, z
	 end
demo% f77 -silent Direct1.f
demo% a.out
demo%

Example: Direct access--read the 3 records:

demo% cat Direct2.f
	 integer u, v, w, x, y, z
	 open( 1, access='DIRECT', recl=8 )
	 read( 1, rec=1 ) u, v
	 read( 1, rec=2 ) w, x
	 read( 1, rec=3 ) y, z
	 write(*,*) u, v, w, x, y, z
	 end
demo% f77 -silent Direct2.f
demo% a.out
  4  5  6  7  8  9
demo%

Here we knew beforehand the size of the records on the file. In this case we can read the file just as it was written.

However, if we only know the size of each item but not the size of the records on a file we can use recl=1 on the OPEN statement to have the I/O list itself determine how many items to read:

Example: Direct-access read, variable-length records, recl=1:

demo% cat Direct3.f
	 integer u, v, w, x, y, z
	 open( 1, access='DIRECT', recl=1 )
	 read( 1, rec=1 ) u, v, w
	 read( 1, rec=13 ) x, y, z
	 write(*,*) u, v, w, x, y, z
	 end
demo% f77 -silent Direct3.f
demo% a.out
  4  5  6  7  8  9
demo%

In the above example, after reading 3 integers (12 bytes), you start the next read at record 13.

 Binary I/O

Opening a file for binary I/O allows the program to read and write data as a stream of binary data without record boundaries. (This feature is not standard Fortran 77).

The FORM='BINARY' option on an OPEN statement declares that unit to be a sequential unformatted file without record marks:

	 OPEN(1, FORM='BINARY') 

A binary file cannot also be declared direct-access or formatted.

On a WRITE statement, binary data is written to the file as a stream of bytes, as many as there are in the output list. On a READ statement, as many data bytes are read as demanded by the variables on the input list. Since there are no record marks (end-of-record) in the file, there will be no possibility of reading past a record mark. Other than abnormal system errors, the only situation that the program can detect is reading in the end-of-file. Each READ statement just reads the next sequence of bytes in the file, as shown in the following example:

demo>cat bin.f
                program bin
                character *25 string
                character *5 word
 
                open(1,FORM='BINARY')
 
                string = 'alphabetagammaepsilon'
 
                write(1) string
                rewind 1
 
                do 1 i=1,6
                word = '     '
                read(1) word
  1             print*, word
 
                end
demo>f77 -o binf bin.f
bin.f:
 MAIN bin:
demo>binf
 alpha
 betag
 ammae
 psilo
 n    
uio: [-1] end of file
logical unit 1, named 'fort.1'
lately: reading sequential unformatted external IO
Abort

An INQUIRE on a binary file returns `BINARY' for the FORM= parameter, `SEQUENTIAL' for ACCESS=, `YES' for UNFORMATTED=, `YES' for SEQUENTIAL.

BACKSPACE on a binary file is not allowed and causes a runtime error message.

List-Directed I/O

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:

The above input stands for 4 complex constants, 2 null input fields, and 4 string constants.

Output Format

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:

Example: No exact binary representation:

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%

In the above example, if you need accuracy, specify the format.

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%

TABLE 5-8   Default Formats for List-Directed Output
Type Format
BYTE
CHARACTER*
n
COMPLEX
COMPLEX*16
COMPLEX*32
INTEGER*2
INTEGER*4
INTEGER*8
LOGICAL*1
LOGICAL*2
LOGICAL*4
LOGICAL*8
REAL
REAL*8
REAL*16
Two blanks followed by the number
An {n = length of character expression}
'(', 1PE14.5E2, ',', 1PE14.5E2, ')'
'
(', 1PE22.13.E2, ',', 1PE22.13.E2, ')'
'
(', 1PE44.34E3, ',', 1PE44.34E3, ')'
Two blanks followed by the number
Two blanks followed by the number
Two blanks followed by the number
Two blanks followed by the number
L3
L3
L3
1PE14.5E2
1PE22.13.E2
1PE44.34E4


COMPLEX*32 and REAL*16 are SPARC only.

Unquoted Strings

f77 list-directed I/O allows reading of a string not enclosed in quotes.

The string must not start with a digit, and cannot contain separators (commas or slashes (/)) or whitespace (spaces or tabs). A newline terminates the string unless escaped with a backslash (\). Any string not meeting the above restrictions must be enclosed in single or double quotes.

Example: List-directed input of unquoted strings:

	 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%

Internal I/O

f77 extends list-directed I/O to allow internal I/O.

During internal, list-directed reads, characters are consumed until the input list is satisfied or the end-of-file is reached. During internal, list-directed writes, records are filled until the output list is satisfied. The length of an internal array element should be at least 20 characters to avoid logical record overflow when writing double-precision values. Internal, list-directed read was implemented to make command line decoding easier. Internal, list-directed output should be avoided.

NAMELIST 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 NAMELIST statement defines a group of variables or arrays. It specifies a group name, and lists the variables and arrays of that group.

Syntax Rules

The syntax of the NAMELIST statement is:

NAMELIST /group-name/namelist[[,]/group-name/namelist]...

Parameter Description
group-name Name of group
namelist List of variables or arrays, separated by commas


See NAMELIST for details.

Example: NAMELIST statement:

	 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.

The input data can include array elements and strings. It can include substrings in the sense that the input constant data string can be shorter than the declared size of the variable.

Restrictions

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.

Output Actions

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 NAMELIST WRITE statement writes values of all variables in the group, in the same order as in the NAMELIST statement.

Example: NAMELIST output:

demo% cat nam1.f 
* nam1.f Namelist output 
	 CHARACTER*8 SAMPLE 
	 LOGICAL*4 NEW 
	 REAL*4 DELTA 
	 NAMELIST /CASE/ SAMPLE, NEW, DELTA 
	 DATA SAMPLE /'Demo'/, NEW /.TRUE./, DELTA /0.1/ 
	 WRITE ( *, CASE ) 
	 END 
demo% f77 nam1.f 
f77 nam1.f 
nam1.f: 
 MAIN: 
demo% a.out 
&case sample= Demo , new= T, delta= 0.100000 
&end 
demo%

Note that if you do omit the keyword NML then the unit parameter must be first, namelist-specifier must be second, and there must not be a format specifier.

The WRITE can have the form of the following example:

	 WRITE ( UNIT=6, NML=CASE ) 

Input Actions

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.

Example: NAMELIST input:

	 CHARACTER*14 SAMPLE 
	 LOGICAL*4 NEW 
	 REAL*4 DELTA, MAT(2,2) 
	 NAMELIST /CASE/ SAMPLE, NEW, DELTA, MAT 
	 READ ( 1, CASE ) 

In this example, the group CASE consists of the variables, SAMPLE, NEW, DELTA, and MAT. If you do omit the keyword NML, then you must also omit the keyword UNIT. The unit parameter must be first, namelist-specifier must be second, and there must not be a format specifier.

The READ can have the form of the following example:

	 READ ( UNIT=1, NML=CASE ) 

Data Syntax

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:

$group-name variable=value [,variable=value,...] $[END] 

You can alternatively use an ampersand (&) in place of each dollar sign, but the beginning and ending delimiters must match. END is an optional part of the last delimiter.

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 


If an array is subscripted, it must be subscripted with the appropriate number of subscripts: 1, 2, 3,...

Use quotes (either " or ') to delimit character constants. For more on character constants, see the next section.

The following is sample data to be read by the program segment above:

$case delta=0.05, mat( 2, 2 ) = 2.2, sample='Demo' $

The data could be on several records. Here NEW was not input, and the order is not the same as in the example NAMELIST statement:

$case 
delta=0.05 
mat( 2, 2 ) = 2.2 
sample='Demo'
$

Syntax Rules

The following syntax rules apply for input data to be read by NAMELIST:

Note an exception--in a character constant, it is ignored, and the character constant is continued with the next record. The last character of the current record is immediately followed by the second character of the next record. The first character of each record is ignored.
Hollerith, octal, and hexadecimal constants are not permitted.
Each constant assigned has the same form as the corresponding FORTRAN constant.
There must be at least one comma, space, or tab between constants. Zero or more spaces or tabs are the same as a single space. You can enter:
1,2,3, or 1 2 3, or 1, 2, 3, and so forth.
Inside a character constant, consecutive spaces or tabs are preserved, not compressed.
A character constant is delimited by apostrophes (') or quotes ("), but if you start with one of those, you must finish that character constant with the same one. If you use the apostrophe as the delimiter, then to get an apostrophe in a string, use two consecutive apostrophes.
Example: Character constants:

sample='use "$" in 2'	 (Read as: use $ in 2)
sample='don''t'	 	 	 	 	 	 (Read as: don't)
sample="don''t" 	 	 	 	 	 	 (Read as: don''t)
sample="don't"  	 	 	 	 	 	 (Read as: don't)

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 

The data for nam2.f is:

$GRID ARRAY = 9,9,9,9,,,,,8,8,8,8 $

This code loads 9s into row 1, skips 4 elements, and loads 8s into row 3 of ARRAY.

Arrays Only

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 

The input for nam3.f is:

$GRID PSI = 5*980 $

The program, nam3.f, reads the above input and loads 980.0 into the first 5 elements of the array PSI.

Example: NAMELIST input with some skipped data.

The other input is:

$GRID PSI = 3* 5*980 $

The program, nam3.f, with the above input, skips the first 3 elements and loads 980.0 into elements 4,5,6,7,8 of PSI.

Name Requests

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:

demo% cat nam4.f
* nam4.f Namelist: requesting names 
	 CHARACTER*14 SAMPLE 
	 LOGICAL*4 NEW 
	 REAL*4 DELTA 
	 NAMELIST /CASE/ SAMPLE, NEW, DELTA 
	 WRITE ( *, * ) 'Input?' 
	 READ ( *, CASE ) 
	 END 
demo% f77 -silent nam4.f
demo% a.out
  Input?
?                                      <-- Keyboard Input
$case
sample
new
delta
$end
 
$case sample="Test 2", delta=0.03 $      <-- Keyboard Input
demo%


Sun Microsystems, Inc.
Copyright information. All rights reserved.
Feedback
Library   |   Contents   |   Previous   |   Next   |   Index