The generic Fortran output statement is write
,
which is an intrinsic subroutine.
A write statement consists of the keyword write
followed by (unit, format) and finally a list
of variables and constants to be written, separated by commas.
write (unit, format) value [, value ...]
The unit number is an integer value that
tells the write statement where to send the output. Each unit
number represents a file stream such
as the standard input, standard output, or standard error.
Opening files and creating additional file streams is covered
in a later chapter.
If a *
is given for the unit number, the write
statement writes to the standard output
stream, which is normally connected to the terminal screen.
The format string is a template for
how the output should look. It specifies how many characters
and how many fractional digits should be printed for real numbers,
for example.
If a *
is used in place of the format string,
the write statement will use default formatting for all items
printed, which is somewhat ugly, but functional.
After the (unit, format) come the items to be written. These may be variables of any type, string constants (characters between quotes), numeric constants, or algebraic expressions.
real(8) :: height, width write (*,*) 'Please enter height and width on the same line:' read (*,*) height, width write (*,*) 'The area is ', height * width
The print
statement is short-hand for
writing to the standard output.
print format, value [, value ...]
is equivalent to
write (*, format) value [, value ...]
Example:
real(8) :: height, width print *, 'Please enter height and width on the same line:' read (*,*) height, width print *, 'The area is ', height * width
The read statement inputs values from a stream such as the standard input and places the values into variables. The components of a read statement are the same as for a write statement.
Providing a *
as the unit number
indicates that the read statement should read from
the standard input stream, which
is normally attached to the keyboard.
real(8) :: height, width, area print *, 'Please enter the height and width on one line:' read (*, *) height, width area = height * width print *, 'The area is ', area
The read statement can also be written in short-hand form like the print statement:
read *, height, width
In Fortran, every read, write or print statement reads or writes
one line of input or output. Unlike C, we cannot
print part of a line with one statement and add to it with
another statement. Fortran print
and
write
statements always appends a newline character
and read always reads to the end of an input line.
Hence, the read statement above expects to find both height
and width on the same line of input. That is, the user cannot
press enter between the numbers.
Likewise, all of the output from a write or print statement will appear on the same line of output. The write or print statement will output all values, and send a newline character after the end of all output, so the next write or print will begin on a new line.
What is the output of the following?
area = 4.0d0 print *, 'The area is ' print *, area print *, '.'
The area is 10.000000000000000 .
To get everything on one line, we must do it in one print/write statement:
print *, 'The area is ', area, '.'
With default formatting, it's not too pretty, but it is on one line as we desired.
The area is 10.000000000000000 .
As mentioned earlier, using a *
in place of the
unit number tells the read statement to use the standard input
stream and the write or print statement to use the standard
output.
If you include the ISO_FORTRAN_ENV module in your program with:
use ISO_FORTRAN_ENV
you can then use the actual unit numbers for the standard streams. The ISO_FORTRAN_ENV module provides the following named constants:
Table 18.4. Standard Stream Names
Unit | Stream |
---|---|
INPUT_UNIT | Standard Input |
OUTPUT_UNIT | Standard Output |
ERROR_UNIT | Standard Error |
For the standard input and standard output, it's easier to type
*
than INPUT_UNIT or OUTPUT_UNIT.
However, to write to the standard error unit, we must use
ERROR_UNIT explicitly.
!----------------------------------------------------------------------- ! Description: ! Find roots of a quadratic equation ! ! Usage: ! quadratic ! ! Returns: ! Nothing !----------------------------------------------------------------------- !----------------------------------------------------------------------- ! Modification history: ! Date Name Modification ! 2011-03-09 Jason Bacon Begin !----------------------------------------------------------------------- program quadratic ! Disable implicit declarations (i-n rule) implicit none ! Local variables real(8) :: a, b, c ! Use complex discriminant so we can get the square root ! even if it's negative. double complex :: discriminant_sqrt, root1, root2, two_a ! Input equation print *, 'Please enter the coefficients a, b, and c on one line:' read *, a, b, c ! Precompute terms that will be used more than once. ! Cast RESULT of all-double expression to complex so that only one ! promotion occurs. ! Convert 2a to complex now to avoid multiple promotions when ! computing the roots. discriminant_sqrt = sqrt(dcmplx(b * b - 4.0d0 * a * c)) two_a = 2.0d0 * a ! Compute roots root1 = (-b + discriminant_sqrt) / two_a root2 = (-b - discriminant_sqrt) / two_a ! Output roots print *, 'The roots of ', a, 'x^2 + ', b, 'x + ', c, ' are:' print *, root1 print *, root2 end program
Output from the program above:
Please enter the coefficients a, b, and c on one line: 1 2 3 The roots of 1.0000000000000000 x^2 + 2.0000000000000000 x + 3.0000000000000000 are: ( -1.0000000000000000 , 1.4142135623730951 ) ( -1.0000000000000000 , -1.4142135623730951 )
As mentioned earlier, one of the asterisks in the write, print, and read statements tells the statement to use default formatting.
The default format is designed to use a consistent number of columns and present accurate information. This often leads to excessive white space and decimal places in the output:
integer :: i = 5 real(8) :: x = 5.0d0 ! Statements print *, i, x
Output: 5 5.0000000000000000 Columns: 123456789012345678901234567890123
As you can see from the "ruler" below the output, the integer is printed across 12 columns, and the real(8) value across 21.
If we want to control the appearance of output or validate the format of input, we can replace the asterisk with a format specifier. The format specifier contains descriptors for each item to be printed, in the same order as the arguments to the read, write or print statement. The first descriptor describes the format of the first argument, and so on.
The most common descriptors are described in Table 18.5, “Common Format Descriptors”.
Table 18.5. Common Format Descriptors
Descriptor | Type | Format |
---|---|---|
Iw | Any integer type | w columns total |
Fw.d | Any real type | w columns total, d decimal places |
Ew.d | Any real type | w columns total, d decimal places, scientific notation |
Aw | String | w columns total |
Gw.d | Any real type | Program chooses the best format |
integer :: i = 5, j = -6 real(8) :: x = 5.0d0, y = -6.0d0 ! Statements print '(i3, f10.2)', i, x Output: 5 5.00 Ruler: 1234567890123 write (*, '(i3, f10.2)'), i, x Output: 5 5.00 Ruler: 1234567890123 print '(i3, e10.2)', i, x Output: 5 0.50E+01 Ruler: 1234567890123 print '(i3, g10.2)', i, x Output: 5 5.0 Ruler: 1234567890123 print '(i3, i3, f10.2, f10.2)', i, j, x, y Output: 5 -6 5.00 -6.00 Ruler: 12345678901234567890123456
If the width is non-zero and the value to be printed doesn't fit, the program will print a '*' instead of the number:
integer :: i = 5, j = -6 real(8) :: x = 5.0d0, y = -6.0d0 ! Statements print '(i1, i1, f4.2, f4.2)', i, j, x, y Output: 5*5.00**** Ruler: 1234567890
If the width is 0, the program will print the minimum number of digits needed to convey the correct value:
integer :: i = 5, j = -6 real(8) :: x = 5.0d0, y = -6.0d0 ! Statements print '(i0, i0, f0.2, f0.2)', i, j, x, y Output: 5-65.00-6.00 Ruler: 123456789012
The width and decimal places specifiers can be omitted for string values, in which case the program will print the string to its full length. This feature can be used with the zero-width descriptor for embedding numbers in text:
integer :: i = 5, j = -6 real(8) :: x = 5.0d0, y = -6.0d0 ! Statements print '(a, i0, a, i0, a, f0.2, a, f0.2)', & 'i = ', i, ' j = ', j, ' x = ', x, ' y = ', y Output: i = 5 j = -6 x = 5.00 y = -6.00 Ruler: 1234567890123456789012345678901234
A format descriptor, or group of format descriptors in () can be preceded by an integer repeat count to shorten the format specifier:
print '(i3, i3, f10.2, f10.2)', i, j, x, y ! Same as print '(2i3, 2f10.2)', i, j, x, y print '(a, i0, a, i0, a, f0.2, a, f0.2)', & 'i = ', i, ' j = ', j, ' x = ', x, ' y = ', y ! Same as print '(2(a, i0), 2(a, f0.2))', & 'i = ', i, ' j = ', j, ' x = ', x, ' y = ', y
Format specifiers can also be used in read statements. If a format specifier is used, then the input must match the format exactly, or an error will be generated. This is done to perform strict checking on input read from a file, if slight deviations in the format might indicate a problem with the data.
If we want to use the same format specifier in multiple print, read, or write statements, we can separate it out to a labeled format statement, and use the label in its place:
print 10, 'i = ', i, ' j = ', j, ' x = ', x, ' y = ', y print 10, 'k = ', k, ' l = ', l, ' v = ', v, ' w = ', w 10 format (2(a, i0), 2(a, f0.2))
What is the "One statement = one line" rule?
What are the names of the standard input, standard output, and standard error streams in Fortran when using ISO_FORTRAN_ENV?
Write a Fortran program that asks the user their name, reads a line of text no longer than MAX_NAME_LEN from the standard input, and prints "Hello, " followed by the name to the standard output.
Write a Fortran program that asks the user for the radius of a circle and the prints the area of the circle.
What is the radius? 10 The area is 314.15926535897933 .