Format

Yutaka Masuda

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.