SuivantPrec.Bas prec.BasNiv. sup.

10.5 Error and End-Of-File Conditions 

Errors in most executable statements can be prevented by taking sufficient care in writing the program, but in I/O statements errors can be caused by events beyond the control of the programmer: for example through trying to open a file which no longer exists, writing to a disc which is full, or reading a data file which has been created with the wrong format. Since I/O statements are so vulnerable, Fortran provides an error-handling mechanism for them. There are actually two different ways of handling errors which may be used independently or in combination.

Firstly, you can include in the I/O control list an item of the form:       IOSTAT=integer-variable When the statement has executed the integer variable (or array element) will be assigned a value representing the I/O status. If the statement has completed successfully this variable is set to zero, otherwise it is set to some other value, a positive number if an error has occurred, or a negative value if the end of an input file was detected. Since the value of this status code is system-dependent, in portable software the most you can do is to compare it to zero and, possibly, report the actual error code to the user. Thus:
 100   WRITE(UNIT=*, FMT=*)'Enter name of input file: '
       READ(UNIT=*, FMT=*) FNAME
       OPEN(UNIT=INPUT, FILE=FNAME, STATUS='OLD', IOSTAT=KODE)
       IF(KODE .NE. 0) THEN
           WRITE(UNIT=*,FMT=*)FNAME, ' cannot be opened'
           GO TO 100
       END IF
This simple error-handling scheme makes the program just a little more user-friendly: if the file cannot be opened, perhaps because it does not exist, the program asks for another file-name.

The second method is to include an item of the form       ERR=label which causes control to be transferred to the statement attached to that label in the event of an error. This must, of course, be an executable statement and in the same program unit. For example:
       READ(UNIT=IN, FMT=*, ERR=999) VOLTS, AMPS
       WATTS = VOLTS * AMPS
 * rest of program in here . . . . . and finally
       STOP
 999   WRITE(UNIT=*,FMT=*)'Error reading VOLTS or AMPS'
       END
This method has its uses but is open to the same objections as the GO TO statement: it often leads to badly-structured programs with lots of arbitrary jumps.

By using both IOSTAT= and ERR= in the same statement it is possible to find out the actual error number and jump to the error-handling code. The presence of either keyword in an I/O statement will allow the program to continue after an I/O error; on most systems it also prevents an error message being issued.

The ERR= and IOSTAT= items can be used in all I/O statements. Professional programmers should make extensive use of these error-handling mechanisms to enhance the robustness and user-friendliness of their software.

There is one fairly common mistake which does not count as an errors for this purpose: if you write a number to a formatted record using a field width too narrow to contain it, the field will simply be filled with asterisks.

If an error occurs in a data transfer statement then the position of the file becomes indeterminate. It may be quite difficult to locate the offending record if an error is detected when transferring a large array or using a large number of records.

End-of-file Detection 

A READ statement which tries to read a record beyond the end of a sequential or internal file will trigger the end-of-file condition. If an item of the form: IOSTAT=integer-variable is included in its control-list then the status value will be returned as some negative number. If it includes an item of the form: END=label then control is transferred to the labelled statement when the end-of-file condition is detected.

The END= keyword may only be used in READ statements, but it is can be used in the presence of both ERR= and IOSTAT= keywords. End-of-file detection is very useful when reading a file of unknown length, but some caution is necessary. If you read several records at a time from a formatted file there is no easy way of knowing exactly where the end-of-file condition occurred. The data list items beyond that point will have their values unaltered. Note also that there is no concept of end-of-file on direct-access files: it is simply an error to read a record which does not exist, whether it is beyond the "end" of the file or not.

Most systems provide some method for signalling end-of-file on terminal input: those based on the ASCII code often use the character ETX which is usually produced by pressing control/Z on the keyboard (or EOT which is control/D). After an end-of-file condition has been raised in this way it may persist, preventing further terminal input to that program.

Formally, the Fortran Standard only requires Fortran systems to detect the end-of-file condition on external files if there is a special "end-file" record on the end. The END FILE statement is provided specifically to write such a record. In practice, however, virtually all Fortran systems respond perfectly well when you try to read the first non-existent record, so that the END FILE statement is effectively obsolete and is not recommended for general use.

SuivantPrec.Bas prec.HautNiv. sup.