« previous next»

2.7    Input, Output, and Format Descriptors

    Obviously, one of the important features of programming is being able to read input (from the keyboard, a data file, etc.) and the output results (to the screen, a data file, etc.).  The general commands available for these actions are:

All of these commands allow for the input or output to be formatted to the programmers specifications.  At the bottom of this chapter is a discussion of format specifiers.
   

OPEN

    Often it is useful in programs to be able to open files for manipulation and use A unit number must be supplied to a file being opened.  the general form of an OPEN statement is as follows:

    OPEN (open-specifiers)

Example:

    OPEN(UNIT = 15, FILE = 'input.dat', STATUS = "OLD", &
                ACTION = "READWRITE", IOSTAT = Open_Status)
    IF (Open_Status > 0) STOP "------------Error, File not opened properly------------"

The file input.dat is opened and assigned a unit number of 15.  If this file is referenced in future READ or WRITE statements then it should be referenced by this unit number.  The file is OLD, meaning it already exists, and it is accessible for reading and writing (READWRITE).  A number is assigned to the variable Open_Status that reflects the ability of the program to open the file.  If it is not opened properly (i.e. Open_Status /= 0) then the next statement halts execution and returns the message "------------Error, File not opened properly------------". It is advisable to use the IOSTAT option whenever opening a file.  In this manner you can halt execution at the point where an error occurs and this will assist with debugging.
 

CLOSE

    Opened files are closed whenever an END of STOP statement is encountered. Alternatively they can be closed at any point of the program by using a CLOSE statement. The general CLOSE statement is:

    CLOSE (close-list)

The close-list must include a unit specifier to indicate what file is to be closed.  Other data can be included but are rarely needed.  If you are interested in other options check the reference material.

Example:

    CLOSE (13)

Closes the file with unit number 13.


READ

    The form of a READ statement is as follows:

    READ (control -specifiers) input-list

    The control-specifiers can contain many items.  A unit specifier is used to indicate the input device (the default is the keyboard).  If a file is opened (with the OPEN command as discussed further down the page) a unit specifier can be assigned to that file.  If data is read from that file then its unit specifier must be indicated.  A format specifier can be the next control-list item.  Input and output data can be formatted as desired and these commands are discussed at the bottom of the page.   Other items that are useful in processing files are available and these can be found in the referenced material.

    The general form of READ statements:

    READ (*,*)    time, concentration
    READ *, time, concentration

The stars (*) indicate the use of default values.  When ()'s are used, the first value is the unit specifier (in this case there is a * so it is the default device, typically the keyboard) and the second value is the format specifier (the * indicates the default, or unformatted data).  The variables time and concentration are read from the default input device and are unformatted.  The second command is the same as the first, just a type of shorthand.
    A typical READ statement:

    READ (15, '(I6, 2F6.2)'), time, conc(1), conc(2)

Here, unit number 15 is specified and the second part is a format descriptor.  The variables read are time, conc(1), and conc(2).

WRITE

    The WRITE command can be used to output data to various devices.  The default (*) for output is the screen.  The general form for a WRITE statement is similar to the other input/output options:

    WRITE (write-specifiers) write-list

The options for write-specifiers are essentially the same as the two previous options.  The first option is the unit identifier which tells which output source is written (* indicates the default screen).  The next option is output format (again, the commands for this will be discussed at the bottom of the page).  By default (*), the output is unformatted.  ADVANCE = expression is an option that indicates where to place the next output. The expression term can be either "NO" or "YES"  If ADVANCE = "NO" then following WRITE statements will begin on the same line as this current output.  If ADVANCE = "YES" then the output is advanced one line and any following output begins on that following line.  If a value for ADVANCE is not indicated then the value of "YES" is used as default.

The write-list consists of the data to be written.  Any data type is allowable in the write-list.  The expressions can be constants, variables, formulas, etc.  The list of expressions are separated by commas.  If no write-list is included then a blank is inserted at the indicated WRITE location.

Example:

    WRITE(*,*, ADVANCE = "NO") "The liquid level in the tank is", Level
    WRITE(*,*) " A level greater than", Level_Max, " indicates a high level alarm."

The output for these commands is:

    The liquid level in the tank is (Level) A level greater than (Level_Max) indicates a high level alarm.

Level and Level_Max are variables.  ()'s are used here to indicate that we do not know the values of these variables.  In truth they will be replaced by numerical values.   Notice that the second WRITE statement begins its output on the same line as the first.  This occurs because the first statement indicates ADVANCE = "NO".  If a third WRITE statement was included then it's output would begin on a new line.
 

PRINT

    The PRINT statement is less versatile than the WRITE statement.  The general PRINT statement is:

    PRINT format-specifier, print-list

PRINT only uses the standard (default) output device.  The print-list  is the data to printed.  Just like the write-list of the WRITE statement the print-list allows use of any data type and the list must be separated by commas.   The output can be formatted using the format-specifier.  A * indicates unformatted data.    A character indicating a format type or a format statement can be used to describe the format.  Again, format statements are described below.

Each PRINT statement begins on a new line of output.
 

FORMAT STATEMENTS

    As previously mentioned input and output can be formatted such that the output is more aesthetically pleasing.  Without format statements output will take on a compiler-dependent form that is generally not appealing.

    The first specification in a format statement is the declaration of the vertical spacing.  The following options are available:

        1X or " " for normal spacing
        "0" for double spacing
        "1" for advancing to the next page before any action
        "+" for overwriting the last line written

    integer formatting

        The letter I is used to describe the format of integer data.  The general form is:

            rIw.m

        Where r is a repetition indicator.  It instructs the number of times this field should be applied.  It is a shorthand (i.e. 3I5.2 = I5.2 I5.2 I5.2).  w determines the width of the field (or number of spaces) used to display the integer.  Blanks are placed in the front of the field (i.e. the output is right justified).  If the number is 4353 and w = 5 then the letter will be written (~ indicates a blank space) ~4353 instead of 4353~.  m is the minimum number of digits displayed. A declaration for m is not required.  For the number 4353, if m = 5 then it will be displayed as 04353.

        Example:

        INTEGER :: A = 12, B = 600, C = 12345
        PRINT '(1X, 2I5.3, I6)', A, B, C

        Output (| indicates the edge of the output area, and ~ are spaces):

        |~~~012~~600~12345

        Here the 1X indicates the vertical single spacing.  A and B are displayed with a minimum of three characters in a field of width five.  Notice that there is always an additional space at the front; so, there are three instead of two spaces in front of A.  C is displayed in a field of width 6, with no declaration of the minimum number of characters.

        If the example were written this way:

        INTEGER :: A = 12, B = 600, C = 12345
        PRINT '(1X, 3I4.3)', A, B, C

        The output would be as follows:

        |~~012~600****

        If the integer number is larger than the field width then the field is filled with *'s.

    real formatting

          rFw.d

        r is the repetition indicator and w the total field width as described before.  d indicates the number of digits to the right of the decimal point.  Simply:

        REAL :: A = -12.5, B = 100.678, C = 3.3
        WRITE (*, '(1X, 2F7.2, F7.3)') A, B, C

        Output:

        |~~-12.50~100.68~~3.300

        Obviously, both the negative sign (-) and the decimal point (.) took up a space in the field.  Also, notice that the value for C was rounded because d = 2 when three numbers were available outside the decimal point.

          rEw.dEe

        Most of the form is similar to the F descriptor, but the output is in exponential form. e indicates the number of positions included in the exponent, but is not required.

       Example:

        REAL :: A = 112.3E8, B = .078e-7
        PRINT '(1X, 2E10.3)', A, B

        Output:

        |~~0.112E+11~0.780E-08

        The exponent indicator (E) and the neg/pos sign require a space in the field.  Also, all exponents are converted so that there is a 0 to the left of the decimal point.
 

          rESw.dEe

        It has the same options as E, but the result is modified so that the value to the left of the decimal point is at least 1 but less than 10.

        In the same example as used for E:

        REAL :: A = 112.3E8, B = .078e-7
        PRINT '(1X, 2ES10.3)', A, B

        Output:

        |~~1.120E+08~7.800E-07

        This gives more precision.

    character formatting

        Character data can be included in format descriptors.  For example:

        INTEGER :: A = 3
        REAL :: B = 0.2
        PRINT '(1X, "A =", I5.2, " B =", F5.2)', A, B

        Output:

        | A =   03 B = 0.20          -or (with ~ as a blank indicator)-         |~A~=~~~03~B~=~0.20

        A can also be used as a format descriptor for character data.  In general:

            rAw

        r is a repetition indicator and w the field width.  Neither are required.  Without w the field width is determined by the character size.  If w is greater than the character size then the output is right justified.  If it less than the character size then the output is the leftmost w characters.

        The A format desccriptor can be used as a place keeper when producing output.  The same PRINT statement from above could be written:

        PRINT '(1X, A, I5.2, A, F5.2)', "A =", A, " B =", B
 
 

« previous next»