Skip to content

10. Printing and files ​

probe writes its vertices: on the screen, into a binary file and a text file, into a stream file from which it reads one vector straight away, and past its end, to see the error.

f90
program probe
!< Tutorial, chapter 10: printing, saving and loading the vertices.
use, intrinsic :: iso_fortran_env, only : int64
use penf, only : R8P
use vecfor, only : ex, ey, ez, vector
implicit none
type(vector)       :: o        ! the origin
type(vector)       :: p(4)     ! the vertices
type(vector)       :: r(4)     ! the vertices read back
integer            :: u        ! a file
integer            :: i        ! counter
integer            :: ios      ! I/O status
character(len=200) :: msg      ! I/O message

p(1) = o ; p(2) = ex ; p(3) = ey ; p(4) = ez
call p(2)%printf(prefix='p2 = ')
call p(2)%printf(prefix='p2 = [', sep='; ', suffix=']')
open(newunit=u, file='vertices.bin', form='unformatted', status='replace')
do i = 1, 4
   call p(i)%save_into_file(unit=u)          ! binary: the exact bits
enddo
rewind(u)
do i = 1, 4
   call r(i)%load_from_file(unit=u)
enddo
close(u)
print '(A,L1)', 'read back equal: ', all(r == p)
open(newunit=u, file='vertices.txt', status='replace')
do i = 1, 4
   call p(i)%save_into_file(unit=u, fmt='(3F6.2)')
enddo
close(u)
open(newunit=u, file='vertices.raw', access='stream', form='unformatted', status='replace')
do i = 1, 4
   call p(i)%save_into_file(unit=u)
enddo
print '(A,I0)', 'bytes per vector: ', o%iolen()
call r(1)%load_from_file(unit=u, pos=2 * int(o%iolen(), int64) + 1)   ! the third vector, straight away
call r(1)%printf(prefix='third vector = ')
call r(1)%load_from_file(unit=u, pos=4 * int(o%iolen(), int64) + 1, iostat=ios, iomsg=msg)
print '(A,I0,2A)', 'reading past the end: iostat = ', ios, ', ', trim(msg)
close(u)
endprogram probe
console
$ probe && cat vertices.txt
p2 = +1.0, +0.0, +0.0
p2 = [+1.0; +0.0; +0.0]
read back equal: T
bytes per vector: 24
third vector = +0.0, +1.0, +0.0
reading past the end: iostat = -1, End of file
  0.00  0.00  0.00
  1.00  0.00  0.00
  0.00  1.00  0.00
  0.00  0.00  1.00

Printing ​

call v%printf writes one line on standard output: the prefix (empty by default), the three components separated by sep (', ' by default), then the suffix (empty). Each number has the shortest digits that read back as the same value. unit= sends the line to another unit, an open file or standard error (see Printing a vector).

Saving and loading ​

call v%save_into_file(unit=u) writes the three components to the unit u, open by you; call v%load_from_file(unit=u) reads them back. Both write or read one record of three numbers, in the form of the unit:

  • unformatted: the exact bits, 24 bytes per double precision vector; what is read back is equal to what was written, r == p.
  • formatted, with fmt=, a format for three reals such as '(3F6.2)': a text file, readable and portable, which keeps only the digits of the format. fmt is a format string; '*' (list-directed) is not supported.

Stream files and positions ​

On a unit opened with access='stream', pos= is the position, in file storage units (bytes, with gfortran), at which the vector is written or read. o%iolen() (or iolen(o)) is the number of storage units of one vector, the value of inquire(iolength=): 24 for double precision. The third vector starts at 2 * 24 + 1, and is read without reading the two before it. pos is an integer(I8P) (64 bits), hence the int(..., int64). For a direct access file, iolen is the record length, recl= (see A direct access file of vectors).

Errors ​

All three procedures take the optional iostat and iomsg of Fortran I/O, and with them the status and the message come back: reading past the end of the file gives iostat = -1, End of file; a malformed number in a text file gives a positive status (see An I/O error caught).

Always pass iostat

Unlike a plain read or write, these procedures never stop the program on an error: without iostat, a failed read or write is silently ignored, and the vector keeps the value it had. Pass iostat and check it.

What you learned

printf with prefix, sep, suffix and unit; save_into_file and load_from_file, unformatted, formatted with fmt, at a position with pos; iolen; iostat and iomsg. Reference: Input and output.

Next: 11. On the GPU.

Released under the GPL v3, BSD 2-Clause, BSD 3-Clause or MIT License.