Formatting and File Handling

Formatted Input and Output

Input from the keyboard and output to the screen are possible using the READ and PRINT statements. So far only list-directed input and output has been encountered, READ * and PRINT *. The programmer has had little control over the way in which data can be input and the layout of printed results. Input and output statements can contain information on how input data should be interpreted and how output data should be laid out. The information is placed in a FORMAT statement.

Edit Descriptors

FORMAT statements contain edit descriptors that provide layout information.

Exponentials are numbers adjusted so they are expressed as: 0.dddd x 10X. In FORTRAN notation such a number is written:

s0.dddd x 10X.

The italicised letters represent the mantissa and the underlined letters, the exponent.

Where:

  • s is sign of the mantissa and sign of the exponent
  • d is significant figures of mantissa
  • x is number of digits in exponent
  •  Variable Type  Edit Descriptor   Specifications
     Integer  I w   w is width of value
     Reals  Fw. d  w is width of value (including negative sign, decimal point and decimal places) of value, d decimal places displayed
     Character  Aw  w characters in width
     Blanks  nX  n blanks
     Exponential  Ew. d  d significant figures in the mantissa, w total width (d + 7 )

    The table below shows the edit descriptor you would use to display each value.

     Value Edit Descriptor
    2099 i4
    -72.81 f6.2
    1.86x105 (+0.186E+06) e10.3
    Cup of Tea a10

     

    The Format Statement

    The general form of the FORMAT statement is:

     label

     FORMAT(c,edl,ed2,'Text message to the screen',ed3...)

    where
     label   is a identifying number for PRINT or READ.
     edl,ed2  are edit descriptors separated by commas
      text  messages are surrounded by single quotes
     c

     is carriage control for OUTPUT only and can be:

     lx   moving the output to the next line
     O  double spacing the output
     +  move to beginning of line, overwriting anything already there
     l  start a new page

    The single quotes around the carriage control codes must be there. A comma (, ) is usually used to separate edit descriptors and text messages but if a slash / is used, instead of a comma, subsequent output will be on a new line. You have to put a carriage control code after a slash to indicate what kind of spacing you want.

    The label on a FORMAT statement replaces the * in a PRINT or READ statement. Up to this point, any text messages you wanted printed out were included in the PRINT * statement. With formatted output you must put the text message in the format statement. Only variable names may be included on a formatted PRINT or READ statement.

    Formatted Input

    Getting a formatted READ to work correctly is very tricky to do. Every blank specified in the FORMAT statement must be present and the values have to appear exactly as specified in the FORMAT statement. The only real advantage of doing a formatted READ iS that character variables do not need single quotes around them to be read in properly.

    There are no rules governing the location of FORMAT statements in programs except that they must be in the same local or sub program unit that refers to them. So any format statements used by the main program must appear in the main program and any format statements used by a subroutine or function must appear within that subroutine or function. Format statements can be placed directly after PRINT and READ statements but some programmers prefer to keep them together near the end of a program.

    File Handling

    So far the programs written have taken input data from the keyboard and the results have been displayed on the computer screen. Data is often input from a file, acted on by a FORTRAN program and output to a file. This is advantageous when the amount of data is large and may be manipulated several times or when the results need to be kept for further calculations.

    The statements for input and output must include details of how and where to input data from and output to. READ * may be expanded to include these controls, however WRITE iS used for output rather than PRINT. Example Program 5 exemplifies common ways of dealing with files: opening, closing, reading from and writing to.

    Input/Output Statements

     READ  (control list) variable list
     WRITE  (control list) variable list

    where the control list items can be a number of the following and are described later on:

     UNIT = unit identifier
     FMT = format identifier
     END = label ERR = label

    Example:

    READ(UNIT = l,FMT = 10)A,B,C

    READ(1,10)A,B,C

    WRITE(UNIT = 2,FMT = 20)X,Y,Z

    WRITE(2,20)X,Y,Z

    Unit identifier

    Every control list must contain a unit identifier. It is this that identifies the location of the file or device to be accessed. If the unit identifier is first in the control list the UNIT = may be omitted. For example:

    WRITE(2,FMT=20)X,Y,Z

    You may choose any number for a unit identifier except for two reserved values that generally have predefined meanings. The number 5 represents keyboard input and 6 represents screen output. So READ(5,*) A,B,C iS another way of writing READ*, A,B,C. Likewise, WRITE(6,*) A,B,C is another way of writing PRINT*, A,B,C.

    Format identifier

    This identifies how the data is organised either by reference to a FORMAT statement or an asterisk indicating list-directed format.

    Example

    READ(UNIT=l, FMT = 10)A,B,C The FORMAT statementitisatlabel l0

    READ(UNIT=1, FMT = *)A,B,C Asterisk (*) means list-directed forrnatting. In other words, no formatting

    If the format identifier is second in the control list the FMT = may be omitted.

    Example

    READ(1,10)A,B,C The more usual concise form.

    End-of-file condition

    Only one end-of-file condition may appear in the control list. When the READ statement reaches the end of the data file without an error occurring, no more data is transferred and the control of the program jumps to the label specified in the READ statement. In the example below, a GO TO statement is used to continue reading from the file until the file is completely read. GO TO statements can be dangerous because they tend to create jumps in control which are hard to follow. It is wise to keep use of GO TO statements to a minimum.

    Example

    80  READ(l,*,END=99)A,B,C
     c  do something with A, B, and C
       GO TO 80
     99

      PRINT *, ALL DATA READ'

    Error condition

    If some error occurs on input/output and there is an error specifier, the input/output is stopped and the program jumps to the label given in the error specifier.

    Example

       READ(l,*,ERR=100,END=200)A,B,C
     100  PRINT *, ERROR ON READING, STOPPING PROGRAM RUN'
       STOP
      c or else continue with the rest of the program
     200 CONTINUE
       END

    A common cause of error in file reading is running out of numbers in the file before the compiler has filled up the requested variables. For example, say that the file accessed by the READ statement above, looked like this:

    12,13,14 
    15 
    16 
    17 
    18 19 20 21 
    22 23

    When the file is initially opened, a pointer is placed at the top of the file. As the file is read, the pointer moves through the file, keeping track of what line has been read and what line has not. The pointer will move for two reasons: l) after a line has been looked at or 2) if the compiler needs more values.

    So after the first read statement, the pointer gets positioned on the line with 15 in it because it was told to look for three values to fill A, B and c and it found all it needed on the first line. The pointer moved on because the line had been examined.

    The second time the READ statement is executed, the pointer is on the line with 18 in it. Again, the compiler was told to look for three values, but they were not on the same line so the pointer moved on to find enough values. When it found all the values it needed the pointer got positioned on the next fresh line, in this case the one beginning with 18.

    The third time the READ statement is executed, the pointer is left on the line beginning with 22. The compiler found the three values it needed on a single line, did not need the fourth value, 21, but moved on anyway.

    During the fourth time the READ statement is executed, the program will have an error. The compiler was told to look for three values in the file. It only found two before it got to the end of the file. So 22 is put into A and 23 is put into B but c does not get a value and the control of the program jumps to line 10 o because that is where it was told to go if there were problems. , Implied DO loops describes a method of reading all the data.

    If later on in the program you want to move the pointer back to the top of the file, the REWIND statement can be used. Example REWIND (UNIT=l)

    Opening and Closing Files

    The OPEN statement

    The OPEN statement connects the file and defines the specifications according to the file specifications list.

    OPEN(UNIT = number,filespec list)

    where the file specifications list can be some of the following:

    ERR = label

    FILE = character, therefore enclosed in quotes

    STATUS = character, therefore enclosed in quotes

    There are more file specifications which can be looked up in one of the recommended texts.

    ERR - If an error condition occurs while the file is being opened, the program jumps to the label.
    FILE - This specifies the name of the file to be opened. The filename is considered a character entity so it must be enclosed in quotes.
    STATUS - This is also a character entity which must be enclosed in quotes
    OLD The file to be opened already exists.
    NEW The named file must not already exist. A file is created and opened.
    UNKNOWN The file may or may not exist.

    The CLOSE statement

    The CLOSE statement disconnects a file:

     CLOSE([UNIT=] number)

    Example Program

     

           program forml 
    c Program calculates the average of three exam scores for a 
    c person. The data is either read not using formatting from 
    c the file, RESLT-UF.DAT, or is read using formatting from 
    c the file RESLT-F.DAT. The output is written to the screen 
    c and to the file RESLT.OUT. NAME is student name. NUMBER is 
    c the student's seat number. EXAMl, 2,are exam results. 
    c AVE is the average of the results. 
    c DECLARATIONS 
           real examl, exam2, exam3, ave 
           character*10 name 
           integer number 
    c FILE OPENING AND VARIABLE INITIALISATION 
           open(unit=9, file='RESLT-UF.DAT', status='old') 
           open(unit=10, file='RESLT.OUT', status='unknown') 
    c INPUT DATA FROM RESLT-UF.DAT WITH AN UNFORMATTED READ 
    c STATEMENT 
           read(9,*) name, number, examl, exam2, exam3 
    c This is how you would write a formatted read statement 
    c even though the program doesn't use it. You would replace 
    c the * in the READ statement above with 15. Also, you 
    c would have to change the data file structure as shown 
    c in RESLT-F.DAT. NOTE THERE IS NO CARRIAGE CONTROL 
    c INDICATOR IN FORMATTED READS 
           15 format(alO,lx, i2,1x, f4.1,1x, f4.1,1x, f4.1,1x) 
    c CALCULATIONS ave=(examl + exam2 + exam3)/3.0 
    c PRINT RESULTS TO SCREEN 
           print 20, name, number 
    20     format(lx,9x,'EXAM RESULTS FOR',al0,/,lx,9x, 
          +'SEAT NUMBER',i3,/,'0') 
           print 25 
    25     format(lx,5x,'TEST 1',5x,'TEST 2',5x,'TEST 3',5x, +'AVERAGE',/,lx) 
           print 30, examl, exam2, exam3, ave 
    30     format(lx, 7x, f4.1, 7x, f4.1, 7x, f4.1, 7x, f4.1) 
    31     format(lx, 4(7x,f4.1) ) 
    c PRINT RESULTS TO OUTPUT FILE 
           write (10,20) name, numberwrite(l0,25) 
           write(l0,30) examl, exam2, exam3, ave 
    c CLOSE FILES 
           close (unit=9) 
           close (unit=10)
           end