next up previous contents index
Next: Pre-Connected Files Up: Input/Output Facilities Previous: Formatted Direct-access Files

Internal Files

An internal file   is an area of central memory which can be used as if it were a formatted sequential file. It exists, of course, only while the program is executing. Internal files are used for a variety of purposes, particularly to carry out data conversions to and from character data type. Some earlier versions of Fortran included ENCODE and DECODE statements: the internal file READ (which replaces DECODE) and internal file WRITE (which replaces ENCODE) are simpler, more flexible, and entirely portable.

An internal file can only be used with READ and WRITE statements and an explicit format specification is required: list-directed transfers are not permitted. The unit must have character data type but it can be a variable, array element, substring, or a complete array. If it is a complete array then each array element constitutes a record; in all other cases the file only consists of one record. Data transfers always start at the beginning of the internal file, that is an implicit rewind is performed each time. The record length is the length of the character item. It is illegal to try to transfer more characters than the internal file contains, but if a record of too few characters is written it will be padded out with blanks. The END= and IOSTAT= mechanisms can be used to detect the end-of-file.

An internal file WRITE is typically used to convert a numerical value to a character string by using a suitable format specification, for example:

      RVALUE = 98.6 
      WRITE(CVAL, '(SP, F7.2)') RVALUE
The WRITE statement will fill the character variable CVAL with the characters ' +98.60 ' (note that there is one blank at each end of the number, the first because the number is right-justified in the field of 7 characters, the second because the record is padded out to the declared length of 8 characters).

Once a number has been turned into a character-string it can be processed further in the various ways described in section 7. This makes it possible, for example, to write numbers left-justified in a field, or mark negative numbers with ``DR" (as in bank statements) in or even use a pair of parentheses (as in balance-sheets). With suitable arithmetic you can even output values in other number-bases such as octal or hexadecimal. Even more elaborate conversions may be achieved by first writing a suitable format specification into a character string and then using that format to carry out the desired conversion.

Internal file READ statements can be used to decode a character string containing a numerical value. One obvious application is to handle the user input to a command-driven program. Suppose the command line consists of a word followed, optionally, by a number (in integer or real format), with at least one blank separating the two. Thus the input commands might be something like:

UP 4 
RIGHT 123.45
A simple way to deal with this is to read the whole line into a character variable and then use the INDEX function to locate the first blank. The preceding characters constitute the command word, those following can be converted to a real number using an internal file READ. For example:
* . . . 
100   WRITE(UNIT=*,FMT=*)'Enter command: ' 
      READ(*, '(A)', IOSTAT=KODE) CLINE 
      IF(KODE .NE. 0) STOP 
      K = INDEX(CLINE, ' ') 
*The command word is now in CLINE(1:K-1); Assume the  
* number is in the next 20 characters: read it into RVALUE 
      READ(CLINE(K+1:), '(BN,F20.0)', IOSTAT=KODE) 
      IF(KODE .NE. 0) THEN 
          WRITE(UNIT=*,FMT=*)'Error in number: try again' 
          GO TO 100 
      END IF
Note that the edit descriptor BN is needed to ensure that any trailing blanks will be ignored; the F20.0 will then handle any real or integer constant anywhere in the next 20 characters. A field of blanks will be converted into zero.

next up previous contents index
Next: Pre-Connected Files Up: Input/Output Facilities Previous: Formatted Direct-access Files
Helen Rowlands