A mechanism is required which permits a programmer to direct input to be performed on data from a source other than the keyboard (during execution time) and to store output in a more "permanent" and capacious form. This is generally achieved by utilizing the computer's filestore which is a managed collection of files. A file such as the source program or a set of I/O data is normally formatted, which means it consists of an ordered set of character strings separated by an end of record marker. A formatted file may be viewed using an editor or printed on a printer. An unformatted file (see later) has no discernable structure and should be regarded as single stream of bytes of raw data. An unformatted file is normally only viewed using a suitable user written program.
Unit numbers may be specified as:
A statement such as a READ, WRITE or OPEN is directed to use a particular unit by specifying the UNIT keyword as follows: UNIT=10 or UNIT=NUNIT. The unit number may also be specified as a positional argument as shown later.
Some computer systems have a naming convention which will "map" unit numbers to default file names, for example when using unit number 10 on a VAX/VMS system this will map to a file called FOR010.DAT and on a Unix to a file called fort.10.
Also some computer systems provide a form of external variable which may be defined prior to execution and the contents of the variable used as a filename. Again on a VAX/VMS system accessing unit 10 will cause an external variable FOR010 to be checked for a filename.
System specific information such as this is provided in the language reference manual on most systems.
READ format-spec,I/O list !This form is not used in this course
or
READ (clist) [I/O list]
where clist is defined as
[UNIT=] unit-number,
[FMT=] format-spec
[,REC= record-number]
[,IOSTAT=ios]
[,ADVANCE=adv]
[,SIZE=integer-variable]
[,EOR=label]
[,END=label]
[,ERR=label]
For example:
READ *,I,J
READ *,LINE
READ 100, I
READ (*,*) A,B,C
READ (5,*) LINE
READ (5,100) X, Y, Z
READ (UNIT=10,FMT=100,ERR=10,IOSTAT=ios)
The unit number and format-specifier must be supplied and in the correct order but the other items are optional. In the last example, if an error occurrs, control passes to the statement labelled 10 and the variable specified as ios will return a positive, system dependent integer. The value 0 will be returned if the operation completes successfully.
WRITE (clist) [I/O list]
where clist is defined as
[UNIT=] unit-number,
[FMT=] format-spec
[,REC= record-number]
[,IOSTAT=ios]
[ADVANCE=adv]
[,SIZE=integer-variable]
[,EOR=label]
[,ERR=label]
For example:
WRITE (*,*)
WRITE (6,*) I,J
WRITE (6,100) I
WRITE (6,*,ERR=10) LINE
WRITE (UNIT=file1,FMT=100,REC=recordnumber, ERR=10) newline
The OPEN statement has the general form:
OPEN (u, [olist] )
where
u is a valid unit number specifier (with or without the keyword)
olist is a list of keyword clauses:
keyword "=" value {"," keyword "=" value}
For example:
OPEN(10)
OPEN (UNIT=10)
OPEN (UNIT=IFILE)
The following keywords are specified in the Fortran 90 language standard:
FILE=filename
where filename is a valid filename for the particular system. Note that case sensitivity is system specific. e.g. FILE='output.test'
STATUS=st
where st may be 'OLD', 'NEW', 'REPLACE', 'SCRATCH' or 'UNKNOWN'. If 'OLD' is specified the file must exist; if 'NEW' the file must not exist; if 'REPLACE' and the file exists it will be deleted before a new file is created; and if 'SCRATCH' the file will be deleted when closed. In general use 'OLD' for input and 'NEW' for output.
ERR=label
GOTO label if an error occurs opening the file.
IOSTAT=ios
where ios is an integer variable which is set to zero if the statement is executed successfully or to an implementation dependent constant otherwise.
FORM=fm
where fm may be 'FORMATTED' or 'UNFORMATTED', the default is 'FORMATTED' for sequential files and 'UNFORMATTED' for direct access files.
ACCESS=acc
where acc may be 'SEQUENTIAL' or 'DIRECT'
RECL=rl
where rl is the maximum record length (positive integer) for a direct access file. For formatted files this is the number of characters and for unformatted it is usually the number of bytes or words (system dependent).
BLANK=bl
where bl is either 'NULL' or 'ZERO' and determines how blanks in a numeric field are interpreted.
POSITION=pos
where pos may be 'ASIS', 'REWIND' or 'APPEND' which are interpreted as positioning the file at the position it was previously accessed, positioning the file at the start; and positioning the file after the previously end of the file. Defaults to ASIS.
PAD=pad
where pad may be 'YES' or 'NO'. If 'YES' formatted input is padded out with blank characters; if 'NO' the length of the input record should not be exceeded.
DELIM=del
where del may be 'APOSTROPHE' or 'QUOTE' or 'NONE' indicating which character used when delimiting character expressions in list-directed or NAMELIST output. Defaults to 'NONE'.
ACTION=act
where act may be 'READ', 'WRITE' or 'READWRITE' specifying the permitted modes of operation on the file. Default is processor dependent.
For example:
OPEN (UNIT=10,FILE='fibonacci.out')
OPEN (UNIT=11,FILE='fibonacci.out',STATUS='NEW',ERR=10)
.......
10 CONTINUE
WRITE(6,*) 'Error opening file: fibonacci.out.'
OPEN (UNIT=12, FILE='student.records', STATUS='OLD', &
ACCESS='DIRECT',RECL=200, FORM='FORMATTED',&
ERR=20, IOSTAT=IOS)
........
20 CONTINUE
IF (ERR .GE. 0) THEN
WRITE (6,*) &
'Error opening file: student.records.'
WRITE (6,*) 'IOS = ',IOS
ENDIF
STOP
If you are in any doubt about the default values for any of the fields of the OPEN statement, especially as some are machine dependent, specify the required values. The combinations of possible error conditions, mean that careful thought should be given to the specification of OPEN statements and the associated error statements. Specifying some values alter the default values of others and some specifies are mutually exclusive, i.e. only one or the other but not both, for example RECL and ACCESS='SEQUENTIAL' may not be used together.
CLOSE ([UNIT=]u [,IOSTAT=ios] [,ERR=label] [,STATUS=st])
where st can be 'KEEP' or 'DELETE'. The value 'KEEP' cannot be applied to a file opened as 'SCRATCH'.
For example:
CLOSE (10)
CLOSE (UNIT=10, ERR=10)
CLOSE (UNIT=NUNIT, STATUS='DELETE',ERR=10)
INQUIRE (inquiry-list)
where inquiry-list may be either
FILE=fname
or
UNIT=unum
plus any combination of the (possible return values are given as a comment)
EXIST=lex ! true or false
OPENED=lod ! true or false
NUMBER=unum ! unit number
NAME=fnm ! filename
ACCESS=acc ! 'DIRECT' or 'SEQUENTIAL'
SEQUENTIAL=seq ! 'YES or 'NO'
DIRECT=dir ! 'YES' or 'NO'
FORMATTED=fmt ! 'YES' or 'NO'
UNFORMATTED=unfmt ! 'YES' or 'NO'
FORM=frm ! 'FORMATTED' or'UNFORMATTED'
NEXTREC=recn ! number of next record for direct access files only
RECL=recl ! record length for direct access files only
Note that recl, recn and unum and integer variables.
CHARACTER (LEN=200) :: STAFFRECORD
OPEN (UNIT=10, FILE='STAFF.RECORDS', &
RECL=200, ACCESS='DIRECT', ......)
READ(UNIT=10,REC=20) STAFFRECORD
WRITE(UNIT=10,REC=20) STAFFRECORD
The ERR and IOSTAT keywords should be used to handle possible error conditions such as reading beyond the end of file. One limitation on a direct access file is that all the records must be of fixed length. On some computer systems a direct access file may not be created by a program but must be created using system commands prior to program execution. Also on some systems such a file may not be extended by the program but must also have a known fixed number of records.
OPEN(UNIT=10,......)
(a) test for the existence of a file called TEMP.DAT
(b) test if a file has been opened on unit 10
(c) test to see if the file opened on unit 15 is a direct access file and if so what the record length is.
The program fragments should output the results in a suitable form.