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.
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:
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 general form of the FORMAT statement is:
label |
FORMAT(c,edl,ed2,'Text message to the screen',ed3...) |
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:
|
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.
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.
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.
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)
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.
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 |