The Queen's University of Belfast
Parallel Computer Centre

[Next] [Previous] [Top]

8 Interactive Input and Output


This module deals with the interaction between a user and the program via the standard input and output devices (keyboard and screen). Data represented by characters, which is a human readable form, are transferred to and from the program. During the transfer process the data are converted to or from the machine readable binary form. In particular the layout or formatting of the data will be considered. A subset of the formatting facilities is presented as the full set is complicated and a number of the features are rarely used.

The process of I/O can be summarised as:



The internal hexadecimal representation of a real number may be

BE1D7DBF

which corresponds to the real value

0.000450

which may be written as

-0.45E-03

This conversion of the internal representation to a user readable form is known as formatted I/O and choosing the exact form of the character string is referred to as formatting. The formatting of I/O is the underlying theme of much of this module.

Consider the I/O statements used in the previous modules:



8.1 FORMAT Statement

The format statement may be used to read or write data in a form other than the default format. A format statement is a labelled statement and may be used by a WRITE or READ statement within the same program unit by specifying the label number as the second parameter to either or by use of a keyword, for example:

READ (*,100) i, j

WRITE (*,100) i, j

READ (*,FMT=200) x, y

WRITE (*,200) x, y

.....

100 FORMAT (2I)

200 FORMAT (2F10.6)

Formatting is sometimes known as I/O editing. The I/O is controlled using edit descriptors. The general form of a FORMAT statement is

label FORMAT (flist)

where flist is a list of edit descriptors which include

I,F,E,ES,EN,D,G,L,A,H,T,TL,TR,X,P,BN,BZ,SP,SS,S,/,:,',(,)

only the following will be covered

I,F,E,ES,EN,A,X,/,:,',(,)

Many edit descriptors can be prefixed by a repeat count and suffixed with a fieldwidth. Thus in the two examples given above, 2I and 2F10.6, could be described as two integers and two floating-point real numbers with fieldwidths of 10.6 (a description follows).

The labelled FORMAT statement may be replaced by specifying the format descriptor list as a character string directly in the WRITE or READ statement, as follows:

READ (*,'(2I)') I, J

WRITE (*,'(2F12.6)') X, Y

This has the advantage of improved clarity, i.e. the reader does not have to look at two statements which may not be consecutive in the source listing to determine the effect of the I/O statement. However, format descriptor lists may be used by more than one I/O statement and a labelled format statement reduces the risk of introducing inconsistencies between the multiple instances of the descriptor list.

8.2 Edit Descriptors

Edit descriptors specify exactly how values should be converted into a character string on an output device or internal file, or converted from a character string on an input device or internal file. The edit descriptors are defined in terms of the following key letters

a repeat count

w width of field - total number of characters

m number of digits

d digits to right of decimal point

e number of digits in exponent

The I/O statement will use as many of the edit descriptors as it requires to process all the items in the I/O list. Processing will terminate at the next edit descriptor which requires a value from the I/O list.

8.2.1 Integer

WRITE (6,`(I10.6)`) 56

would ouput two spaces followed by 0056

8.2.2 Real - Fixed Point Form

WRITE(6,`(2F12.6)`) 12.6, -131.4567891

would output ^^^12.600000 and -131.456789 where ^ represents a space

8.2.3 Real - Exponential Form

8.2.4 Character

8.2.5 Skip Character Positions

8.2.6 Logical

8.2.7 Other Special Characters

8.3 Input/Output Lists

Input/Output lists are used to specify the quantities to be read in or written out. On output expressions may be used but variables are only permitted for input. Implied-DO loops (see below) may be used for either input or output. An array may be specified as either to be processed in its entirety, or element by element, or by subrange; for example:

INTEGER, DIMENSION(10) :: A

READ (*,*) I(1), I(2), I(3)

READ (*,*) I

READ (*,*) I(1:3)

Array elements may only appear once in an I/O list, for example:

INTEGER :: I(10), K(3)

K = (/1,2,1/)

READ (*,*) I(K)

would be illegal as I(1) appears twice.

8.3.1 Derived DataTypes

I/O is performed on derived data types as if the components were specified in order. Thus for P and T of type POINT and TRIANGLE respectively, where

TYPE POINT

REAL X, Y

END TYPE

TYPE TRIANGLE

TYPE (POINT) A, B, C

END TYPE

the following two statements are equivalent

READ (*,*) P, T

READ (*,*) P%X, P%Y, T%A%X, T%A%Y, T%B%X, T%B%Y, T%C%X, T%C%Y

An object of a derived data type which contains a pointer may not appear in an I/O list. This restriction prevents problems occurring with recursive data types.

Any pointers in an I/O list must be associated with a target, the target is the data on which the I/O statement operates, for example:

REAL, POINTER :: PTRA, PTRB

REAL, TARGET :: X

X = 10.0

PTRA => X

WRITE (*,*) PTRA

would output the value 10.0, whereas

WRITE (*,*) PTRB

would generate an error as PTRB is not associated with a target.

8.3.2 Implied DO Loop

The Implied-DO-list, which is often used when performing I/O on an array, has the general form:

(do-object-list, do-var=expr,expr[,expr])

This syntax is similar to the simple indexed DO loop described earlier. Consider the following examples:

INTEGER :: J

REAL, DIMENSION(10) :: A

READ (*,*) (A(J),J=1,10)

WRITE (*,*) (A(J), J=10,1,-1)

The first statement would read 10 values in to each element of I. The second statement would write all 10 values of I in reverse order. The implied-do-list may also be nested

INTEGER :: I, J

REAL, DIMENSION(10,10) :: B

WRITE (*,*) ((B(I,J),I=1,10), J=1,10)

Note:

8.4 Namelist

This is a facility for grouping variables for I/O. The rules governing the use of NAMELIST are fairly complex so, for the scope of this course, only explicitly declared variables will be used, pointers and allocatable arrays will not be covered. The use of NAMELIST for output only will be considered as this can be useful for program testing and debugging. It's use on input is slightly more complicated and is best considered only where necessary.

The NAMELIST statement is used to define a group of variables as follows:

NAMELIST namelist-spec

where namelist-spec is

/namelist-group-name/ variable-name-list

for example

NAMELIST /WEEK/ MON, TUES, WED,THURS, FRI

The list may extended within the same scoping unit by repeating the namelist-group-name on more than one statement, as follows:

NAMELIST /WEEK/ SAT, SUN

More than one group may be defined in one NAMELIST statement but this feature should not be used. Variables should be declared before appearing in a NAMELIST group. Variables with the PRIVATE and PUBLIC attributes should not appear in the same namelist-group. The namelist-group may be used in place of the format specifier in an I/O statement. Only the WRITE statement is considered here.

WRITE (*,NML=WEEK)

will produce

&WEEK SUN=1, MON=2, TUES=3, ...../

where

INTEGER :: SUN, MON, TUES, .....

SUN = 1

MON = 2

.....

Note the output record is an annotated list of the form:

& namelist-group-name namelist-variable=value {,namelist-variable=value} /

This record format must be used for input.

Arrays may also be specified, for example

INTEGER, DIMENSION(10) :: ITEMS

NAMELIST /GROUP/ ITEMS

ITEMS(1) = 1

WRITE (*, NML=GROUP)

would produce

& GROUP ITEMS(1)=1, ITEMS(2:10)=0 /

8.5 Non-Advancing I/O

The normal action of an I/O statement is to advance to the next record on completion. Thus on input if a record is only partially read the rest of the input record is discarded. On output a write statement will complete with the cursor positioned at the start of a new line. Non-advancing I/O permits records to be read in sections (for example a long record of unknown length) or to create a neat user-interface where a prompt for input and the user's response appear on the same line.

There is a complex set of rules covering the use of non-advancing I/O and its various associated keywords. This section only deals with the screen management aspects of this topic.

The ADVANCE keyword is used in write or read statements as follows:

READ(*,*,ADVANCE='YES') ...

WRITE (*,*, ADVANCE='NO') ....

There are two optional keywords, EOR and SIZE, which have the form:

EOR=eor-label

SIZE=integer-variable

The EOR keyword specifies a labelled statement to which control is passed if an error occurs (see ERR keyword later) or if the end of record is encountered. The SIZE keyword specifies an integer variable which is set to the number of characters read.

By default unfilled characters in an input record are padded out with blank characters but these characters are not included in the value assigned to SIZE. The PAD keyword to the OPEN statement (see later) may be used to override the default action.

Examples.

(i)

WRITE(*,*,ADVANCE='NO') 'Enter new value: '

READ(*,*) I

If the user enters the value 10 this would appear on the screen as

Enter new value: 10

(ii)

CHARACTER(LEN=32) :: filename

INTEGER :: length

bb: DO

WRITE (*,*, ADVANCE='NO') 'Filename? '

READ(*,*,ADVANCE='NO',EOR=20, SIZE=length) filename

OPEN(10, FILE=filename(1:length),..)

EXIT bb

20 WRITE(*,'(/A,I)') 'Error: maximum length exceeded.',length

END DO

8.6 Exercises

  1. What values would be read into the variables in the READ statement in the following:

    REAL :: a, b, c

    REAL, DIMENSION (1:5) :: array

    INTEGER :: i, j, k

    READ(*,*) a, b, c

    READ (*,*) i, j, k, array

    given the following input records:

    1.5 3.4 5.6 3 6 65

    2*0 45

    3*23.7 0 0

  2. Given the statements:

    REAL :: a

    CHARACTER(LEN=2) :: string

    LOGICAL :: ok

    READ (*,'(F10.3,A2,L10)') a, string, ok

    what would be read into a, string and ok if the following input records

    were used?

    (a) bbb5.34bbbNOb.true.

    (b) 5.34bbbbbbYbbFbbbbb

    (b) b6bbbbbb3211bbbbbbT

    (d) bbbbbbbbbbbbbbbbbbF

    where b represents a space or blank character.

  3. Write statements to output all 100 elements of a one dimensional array of real numbers with 10 numbers per line each in a total fieldwidth of 12 and having two spaces between each number. The array should be output in fixed point notation with 4 characters following the decimal point and then in floating point notation with three significant digits.

    Hint: An implied DO loop is useful when grouping array elements on the same line.

    Write a program which will initialise all the elements of a suitably declared array to 123.456789 and will test the output statements you have just written. What would happen if the initial value was -123456789.789?

  4. A file contains records in two groups with each group headed by a specification of the format in which the following data is to be read. Each group of data is terminated by the special value 99.9. Write a program to read in all the data. The general form of the input is known i.e.. he first group will contain 3 reals and an integer and the second group one real and an integer. Example data:

    '(3F6.4,I5)'

    3.40 5.6 7.9 10

    4.52 6.3 3.2 11

    99.9 0 0 0

    '(F6.1,I10)'

    4.23 9

    5.89 6

    99.9 0


[Next] [Previous] [Top]
All documents are the responsibility of, and copyright, © their authors and do not represent the views of The Parallel Computer Centre, nor of The Queen's University of Belfast.
Maintained by Alan Rea, email A.Rea@qub.ac.uk
Generated with CERN WebMaker