Format
February 2020
Back to index.html.
Format
We have been used the standard format to print numbers and characters on screen. Sometimes it looks ugly or redundant with many spaces. You can control the output format with an edit descriptor. In this chapter, we will see how to describe the format that you want to have.
Edit descriptors
Basic structure
The edit descriptor is a string enclosed in parenthesis like (descriptor)
. The descriptor is a combination of alphabets/symbols plus a number like i5
and i12
. The alphabet (or symbol) represents the type of object, and the number specifies the width of the output. See the following example.
program form
print *,123
print "(i5)",123
end program form
123
123
The first one is the default output, which has many spaces. The second shows an integer number (i
) with 5 character width (5
), so the descriptor is i5
.
If the value does not fit the format, several *
will be shown.
program form
print *,123
print "(i2)",123
end program form
If you have multiple objects to be shown, the edit descriptor contains multiple items separated by commas (,
). The following example shows 3 integer numbers in a different format.
program form
print "(i5,i8,i4)",123,456,789
end program form
If you want to use the same format for all items, you can unify the descriptor with the number of repeats in front of a single descriptor like (3i5)
or (3(i5))
. If you are not sure how many times you should repeat the format, you can use *()
for this purpose (do not forget the parenthesis; *(i5)
is valid, but *i5
is not).
program form
! all the same format
print "(i5,i5,i5)",123,456,789
print "(3(i5))",123,456,789
print "(3i5)",123,456,789
print "(2i5,i5)",123,456,789
print "(100i5)",123,456,789
print "(*(i5))",123,456,789
end program form
The edit descriptor is an ordinary string so that you can store it in a character variable.
program form
implicit none
character(len=32) :: fmt
fmt = "(*(i5))"
print fmt,123,456,789
end program form
An array is a collection of values, and each one of them can be treated as a single value in the output (and input). See the following example.
program form
implicit none
integer :: a(3)
a = [5,6,7]
! all the same output
print "(3i5)",5,6,7
print "(3i5)",a
print "(*(i5))",a
! different for the last one
print "(2i5,i8)",a
end program form
Data type
Integer
There are several ways to specify the integer output.
Descriptor style | Example | Description |
---|---|---|
i + a single number (\(m\)) |
i10 |
put the integer number (and the negative sign) with the field width \(m\), aligned to the right-hand side; filled by spaces. |
i + 0 |
i0 |
same as above but no alignment and no filler. |
i + two numbers with dot (\(m.n\)) |
i10.5 |
same as above; filled by 0 at least \(n\) digits instead of spaces |
See the following examples.
program form
print "(i6)",123
print "(i0)",123
print "(i6.4)",123
print "(i6.6)",123
end program form
123
123
0123
000123
Real
For real variables, there are 2 categories of output: floating-point format or exponential format.
Descriptor style | Example | Description |
---|---|---|
f + two numbers with dot (\(m.n\)) |
f8.4 |
put a real number (and the negative sign) with the field width \(m\), at least \(n\) digits under the decimal point; aligned to the right-hand side; filled by spaces. |
e + two numbers with dot (\(m.n\)) |
e11.3 |
put a real number (and the negative sign) with the entire field-width \(m\) and the significand field-width \(n\); aligned to the right-hand side; significand between 0 and 1; filled by spaces. |
es + two numbers with a dot (\(m.n\)) |
es11.3 |
same as above except that the significand is between 1 and 10 (friendly with scientific notation) |
g + two numbers with dot (\(m.n\)) |
g11.3 |
choose either f or e automatically (with a slightly different output; see a reference book). |
If a given value has more precision than the descriptor, extra digits of the original value will be rounded. See the following examples.
program form
print "(f8.3)",3.1415926
print "(e11.3)",3.1415926
print "(es11.3)",3.1415926
print "(g11.3)",3.1415926
end program form
3.142
0.314E+01
3.142E+00
3.14
Logical
The format is l
+ a number for the field width. The output is usually T
for true or F
for false.
program form
implicit none
integer :: i
i = 10
print "(l3)",i>0
print "(l3)",i==5
end program form
Characters
There are two descriptors available.
Descriptor style | Example | Description |
---|---|---|
a |
a |
put characters with the same size as defined; no alignment. |
a + a single number \(m\) |
a10 |
put characters with the field width \(m\); discarding extra characters not fitting to the format; aligned to the right-hand side; filled by spaces. |
See the example.
program form
print "(a)", "Yes, it is."
print "(a20)","Yes, it is."
end program form
Yes, it is.
Yes, it is.
Other useful descriptors
The Fortran standard defines many descriptors, but some of them can very precisely control the output. Here, we only look at the most frequently-used descriptors.
Spaces
The x
descriptor shows a space. When putting multiple spaces, combine a number with it, e.g., 5x
for 5 spaces.
program form
print "(a,3x,a)","abc","def"
end program form
Note that whereas 3x
is valid, x3
is invalid.
New line
The /
descriptor makes a new line.
program form
print "(a,/,a)","abc","def"
end program form
Characters
If you want to print some characters, you can put it into the edit descriptor. The characters should be encircled by "
or '
.
program form
print "('result=',i8)",1+2
end program form
The above code is equivalent to the following program.
program form
print "(a,i8)","result=",1+2
end program form
Formatted input
We have seen a formatted output with print
. In turn, we can use the formatted input with read
. I have a concern in the formatted input; it results in trouble when the input sequence does not follow the rule in the descriptor. Also, you would be confused by some non-intuitive behavior in formatted input. Although the language standard defines what happens when the input is not appropriate, it might be hard for us to figure out what is going on when it is happening.
Formatted read
It is always good to see how it works using a small program.
program form
implicit none
integer :: i
read "(i10)",i
print *,i
end program form
The following is a pair of an input and the corresponding output (with GFortran).
# when putting "1"
1
# when putting " 1"
1
# when putting " 1"
0
# when putting "1 2 3"
123
# when putting "a"
At line 4 of file form.f90 (unit = 5, file = 'stdin')
Fortran runtime error: Bad value during integer read
...
You may see some rules in it, but the rule is very confusing, particularly in 1 2 3
.
In my opinion, the formatted input should be used when 1) it is the only way to do or 2) the input is expected to be correct with the edit descriptor. Otherwise, the default input *
should be easier to handle. Here we will see some examples of how the formatted input works.
Formatted characters
There are a few cases where the formatted input is useful. One such situation is in reading characters with spaces. Using the edit descriptor a
, you can obtain the characters with spaces.
program form
implicit none
character(len=10) :: a
read "(a)",a
print *,a
end program form
Fixed format
The other case is in reading a fixed-format file. If a text file contains some fields and each field is aligned to a particular column, this file is called fixed format. For example, an SNP file with 0-1-2 coding is a fixed-format file.
id01 012012012
id02mx 211102111
id03f 012001101
The second field (genotypes) strictly starts from the 9th column. This small file can be seen as a space-separated file, but the fixed-format file should have a constant format for all the rows. We will see how we can read a file in later chapters. We try to read such a structure using formatted input.
We assume that an individual has 9 markers, which are integer numbers. Ignoring the first field and leading spaces by skipping the first 8 characters, the edit descriptor for the second field is (8x,9i1)
. The program looks like this.
program form
implicit none
integer :: g(9)
read "(8x,9i1)",g
print *,g
end program form
Back to index.html.