Community
cancel
Showing results for 
Search instead for 
Did you mean: 
MWind2
New Contributor I
233 Views

Write Derived Type Formatted to Disk

How does one format a derived type to be saved with formatting, and later be read back into instance(ignore round trip variable equality for reals)?  Sample with bad format attempt:

program ftype

    implicit none

    ! Variables
    integer ios10
    type t0
        character(len=32)   :: name = '.'
        real, dimension(56) :: awclose = -1.0
        integer             :: id = -1
        LOGICAL             :: IS_IT_INITIALIZED = .FALSE.
    end type t0
   type(t0), dimension(4)         :: at0
    ! Body of ftype
    
    open (10,file='testat0.dat',form='FORMATTED',access='sequential',IOSTAT=ios10)
    write (10,10) at0(1)
    !
    !10   FORMAT (t0%name, t0%awclose 5F15.8, t0%id)
    close (10)
    end program ftype
0 Kudos
4 Replies
Steve_Lionel
Black Belt Retired Employee
225 Views

Fortran 2018 has a treat for you - EX format. This writes (and reads) reals in a hexadecimal notation that reproduces the bit pattern exactly.  It's supported in the Intel 2021 beta (and will be when it becomes a product.)

Here's a modified version of your example that demonstrates the feature (I am not sure what you intended with that commented-out FORMAT that isn't a format.)

program ftype

    implicit none

    ! Variables
    integer ios10
    type t0
        character(len=32)   :: name = '.'
        real, dimension(5) :: awclose = -1.0
        integer             :: id = -1
        LOGICAL             :: IS_IT_INITIALIZED = .FALSE.
    end type t0
   type(t0), dimension(4)         :: at0
    ! Body of ftype
    
    call random_number(at0(1)%awclose)
    print *, at0(1)%awclose
    open (10,file='testat0.dat',form='FORMATTED',access='sequential',IOSTAT=ios10)
    write (10,10) at0(1)
    10 format (A,1X,5EX16.6E2,1X,I5,1X,L1)
    rewind (10)
    read (10,10) at0(2)
    print *, at0(2)%awclose
    !
    !10   FORMAT (t0%name, t0%awclose 5F15.8, t0%id)
    close (10)
    end program ftype
D:\Projects>ifort t.f90
Intel(R) Visual Fortran Intel(R) 64 Compiler for applications running on Intel(R) 64, Version 2021.1 Beta Build 20200602
Copyright (C) 1985-2020 Intel Corporation.  All rights reserved.

Microsoft (R) Incremental Linker Version 14.27.29111.0
Copyright (C) Microsoft Corporation.  All rights reserved.

-out:t.exe
-subsystem:console
t.obj

D:\Projects>t.exe
  3.9208680E-07  2.5480442E-02  0.3525161      0.6669145      0.9630555
  3.9208680E-07  2.5480442E-02  0.3525161      0.6669145      0.9630555

D:\Projects>type testat0.dat
.                                  0XD.280000P-25  0XD.0BC5C0P-09  0XB.47CFF0P-05  0XA.ABAE80P-04  0XF.68ACE0P-04    -1 F
MWind2
New Contributor I
212 Views

The following seems to do most of what was desired:

program ftype

    implicit none

    ! Variables
    integer i
    integer ios10
    type t0
        character(len=32)   :: name = '.0123456789'
        real, dimension(56) :: awclose = -1.0
        integer             :: id = -1
        LOGICAL             :: IS_IT_INITIALIZED = .FALSE.
    end type t0
   type(t0), dimension(4)         :: at0
    ! Body of ftype
    do i=1, 56
        at0(1)%awclose(i) = at0(1)%awclose(i)+i*1.0
    end do
    open (10,file='testat0.trgx',form='FORMATTED',access='sequential',IOSTAT=ios10)
    write (10,10) at0(1)
!10  FORMAT (A32,5F15.6, 5F15.6, 5F15.6, 5F15.6, 5F15.6, 5F15.6, 5F15.6,5F15.6,5F15.6,5F15.6,6F15.6,I8,L2)
    10   FORMAT (A32,56F15.6, I8,L2)
    close (10)
    end program ftype

It would seem that formatting 5 floats and then a crlf would defeat the delimiters of a record so to display would need more code and the result not be readable as a t0 record

andrew_4619
Honored Contributor I
196 Views

Steve clearly changed the example to 5 just to make it more compact to display the output. Note that he changed the derived type component to 5 elements also. It seem you have a working solution know.

 

Steve_Lionel
Black Belt Retired Employee
189 Views

Generally if you format reals to three more significant digits than the datatype holds, you won't lose any bits. For single precision, I'd suggest 10 digits.

Reply