2-10 USING I/O FORMATS
***********************
(Thanks to Craig Burley for the very important contributions to
this chapter)
A short glossary of formatting terms
-------------------------------------
FORMAT STATEMENT 100 FORMAT (I5,/,I5,1E15.5)
EMBEDDED FORMAT write(*,FMT='(I5,/,I5,1E15.5)') I, J, X
FORMAT SPECIFICATION (I5,/,I5,1E15.5)
RECORD TERMINATOR '/' or ')'
FIELD DESCRIPTOR 'I', 'E'
FIELD SEPARATOR ','
Standard format types: constant vs. run-time
--------------------------------------------
An interesting fact about formats is that the format string is
passed to an I/O routine that translates AT RUNTIME the information
it contains and executes it, so you can change format strings
'dynamically' while the program is running and everything will
work o.k.
The technique of constructing format strings dynamically (at runtime)
and using them in I/O statements, is called RUN TIME FORMAT, and is
more powerful than variable format (see later in this section),
but has a high performance cost.
A small program will illustrate this point:
PROGRAM RUNFMT
C ------------------------------------------------------------------
REAL
* X
C ------------------------------------------------------------------
PARAMETER(
* X = 0.123456789)
C ------------------------------------------------------------------
CHARACTER
* STRING*80
C ------------------------------------------------------------------
100 CONTINUE
WRITE(*,*) ' Enter a format string suitable for one float '
WRITE(*,*) ' Don''t forget the ''()'' ! '
READ(*,FMT='(A80)') STRING
C ------------------------------------------------------------------
WRITE(*,FMT=STRING) X
GOTO 100
C ------------------------------------------------------------------
END
Clever compilers notice if the format string is a constant and
translate it at compile time.
The FORMAT statement is always compiled to at least some degree
(must be parsed to determine that it's really a FORMAT statement,
unless the compiler is buggy); a _constant_ in a variable FORMAT
context _might_ be compiled (and syntax-checked); a _variable_ in
a variable FORMAT context is rarely compiled or syntax-checked
(though with some pretty nifty data flow analysis, I suppose this
could be done).
WRITE (6, 10) ...
10 FORMAT (...) ! this is basically always "compiled" and checked
WRITE (6, '...') ! this _might_ be compiled/checked
WRITE (6, FMTVAR) ! this _rarely_ is compiled or checked
Of course, what "compiled" means differs from compiler to compiler --
f2c/g77 currently just digest and reproduce the character string,
taking out some unnecessary things like spaces I believe (but that's
only for FORMAT statements), so _all_ FORMAT strings, however they're
coded, will be re-interpreted at run time for those compilation systems.
(FORMAT-using code is rarely, and should not, be used in the midst of
code needing high performance; unformatted I/O is almost always superior
in this context.)
Variable format
---------------
Variable format is non-standard in all Fortrans, and is not
widely supported either, however it's an efficient extension.
Variable format allows you to specify not only constants,
but also variables in a format specification.
The variables are enclosed by angle brackets:
INTEGER intvar1, intvar2
REAL realvar
......................................
READ(UNIT=*, FMT=*) intvar2
intvar1 = intvar2 + 7
WRITE(UNIT=10, FMT='(1X, E<intvar1>.<intvar2>)') realvar
Variable format is flexible, and can change while the program runs,
it is executed more efficiently than run-time format.
Embedded format specification
-----------------------------
INTEGER intvar
REAL realvar
......................................
WRITE(UNIT=10, FMT='(1X, I5,E15.5)') intvar, realvar
It is usually nicer to have the format string inside the I/O
statement, at least if the format string is not long.
Using the 'A' format
--------------------
CHARACTER string*80
......................................
READ(UNIT=10, FMT='(A)') string
Using just 'A' without a 'size' is standard. It provides a flexible
way to read and write strings, without having to specify explicitly
their sizes. The length of the associated string is taken as the
format 'width parameter'.
Radix conversions in formatted I/O
----------------------------------
Formatting routines should not truncate numbers but round them,
(see the chapter on radix conversion and rounding).
A vendor may do correct (or nearly correct) IEEE rounding for all
values, or use some other scheme, for example DEC rounds {0,1,2,3,4}
down and {5,6,7,8,9} up.
Most vendors don't do correct IEEE rounding.
Return to contents page