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