
. Introduction to Fortran 90 : Part 2
7. About input and output
So far in the course you have used simple "free format" read and write
statements to control input from the keyboard and output to the screen.
This section shows how to extend these to:
• Accept input from sources other than the keyboard and direct output to
locations other than the screen (e.g. to a file).
• Specify the precise format of the input or output.
7.1 Redirection of input/output
By default, input is read from the keyboard and output is displayed on the
screen. These defaults are indicated by the first * in the read(*,*) or
write(*,*) statement. When you want to read from somewhere else, or to
write to somewhere else, this * should be replaced with a unit identifier
which identifies a particular location for the input or output. The unit
identifier is simply an integer or an integer expression. It is best to use
small, positive integers (less than 64) because the permissible range varies
between systems.
Note that, by tradition, unit 5 is used as a default for the standard input unit
(almost always the keyboard), 6 is a default for the standard output unit
(almost always the screen) and 0 is the default unit for errors, so when you
use other files/devices it is normal not to use these numbers.
Apart from the keyboard for input and the screen for output, the most
frequent location for input/output is a file. Before a file can be accessed
from a read or write statement in your program, the program must make a
connection between the actual file concerned and the Fortran unit. This is
done with an open statement.
Example
Imagine that you wish to read some input from a file called info.dat which
is in the directory /scratch/share/dxy3abc. You could use 10 as the
number for this input unit. In order to make a connection to the file, you
would include the following statement in the program, before the first time
you try to read from the file:
open(10,file='/scratch/share/dxy3abc/info.dat')
Notice that the filename /scratch/share/dxy3abc/info.dat is in quotes as is
normally the case for character strings in Fortran. You can also use the
lengthier, more explicit version of the statement:
open(unit=10,file='/scratch/share/dxy3abc/info.dat')
After the open statement, any subsequent references to unit 10 in read
statements will automatically be directed to this file. So, for example, in
order to read data from info.dat you might use:
read(10,*)k,l,m
to read free-format data from the file into the three integer variables k, l and
m. Each successive read will (normally) cause input to be read from the
next line in the file.
Writing to a specific location is done in exactly the same way as reading. In
order to write to unit 11 (a file), we would first need to open the file and
then use, for example:
write(11,*)k,l,m
As with read statements, each successive write statement will normally
direct output to the next line in the file.
When a file is no longer required (e.g. when the program has finished
reading data from it) the connection between the unit identifier and the file
should be closed by making use of the close statement. To close the
connection with unit 10, the statement would be:
close(10)
Note: output files may appear incomplete or empty until the close
statement has been executed or the program exits.
Exercise
As a demonstration of output to a file, type the following program into a file
called output1.f90, then compile, link and run the program and inspect the
results in the file out.dat, which will be in your current directory. Note that
the program writes no output on the screen, only to the file.
program output1
implicit none
integer:: iyears, imonths, iage
character (LEN=30):: name
!
! Simple program to send output to a file.
!
write(*,*)' Hello. What is your name (type it in single quotes)'
read(*,*)name
write(*,*)' How old are you (years and months)?'
read(*,*)iyears, imonths
iage = iyears * 12 + imonths
open(1,file='out.dat')
write(1,*)name, ' is ',iage,' months old!'
close(1)
stop
end program output
Formatting input and output
Sometimes the default format that Fortran uses for input and output is not
sufficient. For example, you may need to read data from a file that contains
a specific layout, or you may want a neater layout for your output. You can
control the format of input or output with a format statement. Format
statements have a particular syntax, for example:
10 format(i2,i4)
Every format statement begins with a number that identifies it, called the
statement label. After the statement label there is a space and then the
word format. The expression in the brackets defines the precise format in
which the data are to be input/output. The example above uses I-format,
which is for integers. The i2 indicates that the first item is an integer
composed of two digits, and the i4 indicates that the next item is a four-digit
integer. Unlike executable statements, a non-executable format statement
like this one can appear anywhere within the program, before or after the
associated read/write statement. It can also be used with more than one
read/write. In a program with many format statements, it is a good idea to
group them together at the beginning or end of the program so that it is
easy to find them.
Note: if a format statement continues over more than one line, it should
have a & character at the end of the first line and another & at the
beginning of the next line.
To make use of a format statement, replace the second * in a read
statement or a write statement by the label for the format statement. For
example:
write(*,10) i,j,k
10 format(i2,i4,i10)
This example again uses I-format. It writes the variables i, j and k as a 2-
digit integer, a 4-digit integer and a 10-digit integer.
When you use a format statement with a write statement, the formats do
not necessarily have to match the number of digits in each variable. If a
number is smaller than the size allowed in the format statement, it will be
padded with spaces (to the left of the number). If it is too large for the
format, then it will be replaced by a row of ***** -- if this happens you will
probably need to edit your program to solve the problem.
When you use a format statement with a read statement, be more careful.
If the format you specify is too small for the number you want to read, it will
be truncated (i.e. wrong). If the format is too large, you may read characters
that should not be included.
Note: for short format statements that you will use only once, the format
can be inserted directly into the read/write statement in the following way:
write(*,'(i2,i4, i10)') i,j,k
The I-format that you have seen so far is for integers. Other format types
are used for the other variable types. The most commonly encountered
formats are:
In the descriptions of the formats, the term character is used to indicate the
symbols on the screen, whether they are digits, letters or spaces. In the
case of numbers the characters are interpreted in the form of the
appropriate integer or real numbers. Whenever the decimal point is
included, it counts as one character in the field width. The total field width
includes any minus sign and any leading spaces.
To specify multiples of a format, prefix the format specification with the
number involved. For example, to read one 2-digit integer followed by two
8-digit integers, you could use the format statement:
10 format(i2,2i8)
It is also possible to specify where new lines start, using the / symbol. To
read four 3-digit integers from line 1 of the file and another two from line 2,
the format statement could be:
10 format(4i3/2i3)
Any data on line 1 beyond the first four integers will be ignored.
Note that a comma is required to separate the items in a format statement,
except when there is a / between them to indicate that data continue on the
next line.
Normally the number of variables in a read or write statement should
match the number of items in the format statement. If there are more
variables than items in the format statement, as in the example below, the
format is simply repeated until all the variables have been processed.
read(1,10) i,j,k,l,m,n
10 format(3i2)
Here, i, j and k will be read from one line and l, m and n would be read from
the next line in the same format.
Note that on some computers, unless the output is being directed to a file,
the first character of each line may be treated as a "carriage control"
character when the output is displayed or printed and, unless you ensure
that the first character is a space, the output may not look as you intended.
(In particular, you may lose a minus sign or the first character of the field!).
For this reason, you will find that programs often begin output formats with
a space (1x). For more information on this topic, please consult the sources
listed at the end of the course.
Exercise
When you read data, you will often find it easier not to use a format
statement, because the data are forced into the format that you specify. To
illustrate this point, type the following program into a file called format1.f90
program format1
implicit none
integer:: i, j
real:: x
character(len=10):: mychars
!
! Simple program to demonstrate the use of the format statement
!
write(*,*)' Enter digits 0 to 9 twice in succession '
read(*,100)mychars, i, x, j
100 format(1x, a5, i5, f6.2, i3)
write(*,*)mychars, i, j, x
stop
end program format1
Run the program and enter 01234567890123456789 when requested.
The 1x in the format statement causes the first digit (0) to be skipped. The
next 5 digits, 1 to 5, are interpreted as characters (a5) and are entered into
the first 5 places of the 10-character variable, mychars. The integer value
67890 is placed in variable i according to the i5 specification. The next 6
digits, 123456, are interpreted as 1234.56 because of the f6.2 and are
placed in x and, finally, j is given the value 789 as required by the i3
format. Check this by looking at your output. Then see what happens if
(a) you change the format statement to
100 format(a8, i4, 2x, f4.2, i2)
(b) you change the format statement so that it does not match the variable
types, e.g:
100 format(a8, f4.2, 2x, i4, i2)
In the exercise above, you used format f6.2 to deal with the real variable x.
This defined the decimal point to be between the 4th and 5th digit in the
format and it was inserted there even though there was no decimal point in
the input data. In practice, the decimal point should usually be included in
the input data: provided that the number fits into the field width, it will be
recognised correctly. If the number is negative then the minus sign must
also fit within the field.
7.3 E format and D format
A frequent problem with formatted output is that a number is too big to fit
into the specified field width. For example, 9999999.0 does not fit into
format F6.2, which can only deal with the correct output of numbers up to
999.99. When this happens, the entire number is replaced in the output by
asterisks, e.g. ******. If you are not sure how big an answer will be, consider
whether it would be better to display it with E-format (exponential format),
which is the best way to display numbers that are (or could be) very large
or very small.
For example, a number 1.234567 x 10-12 displayed in E14.7 format would
appear as:
0.1234567E-11
where the E14.7 specifies 7 characters after the decimal point and 7 other
characters. There is an equivalent D-descriptor form for double precision
numbers. For example, D14.7 format would give output such as:
0.1234567D-11
Note that the total width of E- and D- format fields (14 in these examples)
must be big enough to accommodate any minus sign, the decimal point and
the E-nn, so it is recommended that the total field width should always be at
least 7 places more than the number of digits required after the decimal
point.
Exercise
To practise using format statements, make a copy of your program
output1.f90 and call the copy output2.f90. In output2.f90, change the line:
write(1,*) name, ' is ',iage,' months old!'
to
write(1,100) name, iage
100 format(a30,' is ',i4,' months old!')
Check that the output matches the format statement.
You have already seen the intrinsic functions real, dble, int and nint, which
converted variable values from one type to another. Fortran 90 has over
100 intrinsic functions. Some of the most frequently used ones are:
expression. These functions will not accept integer arguments. The output
of the function will be real for real x and double precision for double
precision x.
Note: all trigonometric functions use radians and not degrees. 2 radians =
360 degrees.
Exercises
1) The formula for calculating compound interest is:
where final is the final value, start is the start value, rate is the
annual interest rate in percent, and nyears is the number of years.
Write a program called money.f90 that calculates the value of a
£1000 investment after 5 years, for interest rates of 2, 4, 6 and 8%
and writes the interest rates and results neatly on the screen and in
a file called mymoney.
2) Write a program readmoney.f90 which reads the interest rates and final
sums from the file mymoney and then displays them on the screen.
3) Write a program called trig.f90 that prompts for an angle in degrees from
the keyboard and then prints out neatly on the screen the sine, cosine
and tangent of the angle.

0 Comments