Intel® Fortran Compiler Classic and Intel® Fortran Compiler Developer Guide and Reference

ID 767251
Date 9/08/2022
Public

A newer version of this document is available. Customers should click here to go to the newest version.

Document Table of Contents

Examples of User-Defined Derived-Type I/O

Example 1

The following example shows formatted defined I/O using the DT edit descriptor and both generic type-bound and explicit interface procedures:


MODULE TYPES
  TYPE T
     INTEGER :: K(10)
   CONTAINS

! a generic type-bound procedure
     PROCEDURE :: UDIO_READ_ARRAY
     GENERIC :: READ (FORMATTED) => UDIO_READ_ARRAY
  END TYPE T

! an explicit interface
  INTERFACE WRITE(FORMATTED)
     MODULE PROCEDURE UDIO_WRITE_ARRAY
  END INTERFACE
 CONTAINS
  SUBROUTINE UDIO_READ_ARRAY (DTV, UNIT, IOTYPE, V_LIST, IOSTAT, IOMSG)
    CLASS(T), INTENT(INOUT)     :: DTV
    INTEGER, INTENT(IN)         :: UNIT
    CHARACTER(*), INTENT(IN)    :: IOTYPE
    INTEGER, INTENT(IN)         :: V_LIST (:)
    INTEGER, INTENT(OUT)        :: IOSTAT
    CHARACTER(*), INTENT(INOUT) :: IOMSG
 
! This is the child I/O that gets performed when the procedure
! is called from a parent I/O – it uses list-directed input to read
! the array K

    READ (UNIT, FMT=*, IOSTAT=IOSTAT, IOMSG=IOMSG) DTV%K

    END SUBROUTINE UDIO_READ_ARRAY

  SUBROUTINE UDIO_WRITE_ARRAY (DTV, UNIT, IOTYPE, V_LIST, IOSTAT, IOMSG)
  CLASS(T), INTENT(IN)        :: DTV 
  INTEGER, INTENT(IN)         :: UNIT
  CHARACTER(*), INTENT(IN)    :: IOTYPE
  INTEGER, INTENT(IN)         :: V_LIST (:)
  INTEGER, INTENT(OUT)        :: IOSTAT
  CHARACTER(*), INTENT(INOUT) :: IOMSG

! This is the child I/O that gets performed when the procedure
! is called from a parent I/O – it uses list-directed output to write
! the array K

        WRITE (UNIT, FMT=*, IOSTAT=IOSTAT, IOMSG=IOMSG) DTV%K

  END SUBROUTINE UDIO_WRITE_ARRAY

 END MODULE TYPES

 PROGRAM TEST1
  USE TYPES
  TYPE (T) :: V
  INTEGER  :: COUNTCHAR

   OPEN (1, FILE='TEST.INPUT', FORM='FORMATTED')
    READ (1, FMT='(DT)', ADVANCE='NO', SIZE=COUNTCHAR) V
  CLOSE(UNIT=1)
  WRITE(6, '(DT)') V

 END PROGRAM TEST1

Consider that procedure UDIO_READ_ARRAY reads an input file named TEST.INPUT that contains the following:

1, 3, 5, 7, 9, 2, 4, 6, 8, 10

In this case, the program TEST1 in procedure UDIO_WRITE_ARRAY prints:

           1           3           5           7           9           2
           4           6           8          10

Example 2

The following example shows list-directed formatted output and user-defined I/O:


MODULE M
  TYPE T
     REAL, POINTER :: R (:)
   CONTAINS
     PROCEDURE :: UDIO_WRITE_LD
     GENERIC   :: WRITE(FORMATTED) => UDIO_WRITE_LD
  END TYPE T
 
CONTAINS
  SUBROUTINE UDIO_WRITE_LD (DTV, UNIT, IOTYPE, V_LIST, IOSTAT, IOMSG)
    CLASS(T), INTENT(IN)            :: DTV
    INTEGER, INTENT(IN)             :: UNIT
    CHARACTER(LEN=*), INTENT(IN)    :: IOTYPE
    INTEGER, INTENT(IN)             :: V_LIST (:)
    INTEGER, INTENT(OUT)            :: IOSTAT
    CHARACTER(LEN=*), INTENT(INOUT) :: IOMSG
    IOSTAT = 0
    PRINT *, SIZE (DTV%R)
    WRITE (UNIT, *) DTV%R
  END SUBROUTINE UDIO_WRITE_LD
END MODULE M

 
PROGRAM TEST2
  USE M
  TYPE (T)     :: X
  REAL, TARGET :: V (3)

  V = [ SIN (1.0), COS (1.0), TAN (1.0) ]
  X = T (R=V)
  PRINT *, X
END PROGRAM TEST2

TEST2 should print "3 0.8414710 0.5403023 1.557408".

Example 3

The following example shows user-defined derived-type NAMELIST input/output:


! PROGRAM: udio_nml_read_write.f90
!
! This program tests NAMELIST READ and WRITE.  In the WRITE subroutine, there
! are FORMATTED WRITES as well as NAMELIST WRITES.
!
MODULE UDIO
  TYPE MYDT
     INTEGER F1
     INTEGER F2
   CONTAINS
     PROCEDURE :: MYSUBROUTINE
     GENERIC :: READ (FORMATTED) => MYSUBROUTINE
  END TYPE MYDT

  INTERFACE WRITE (FORMATTED)
     MODULE PROCEDURE :: WRITESUBROUTINE
  END INTERFACE
CONTAINS

  SUBROUTINE WRITESUBROUTINE (DTV, UNIT, IOTYPE, V_LIST, IOSTAT, IOMSG)
    CLASS (MYDT),	INTENT(IN)	:: DTV
    INTEGER*4,		INTENT(IN)	:: UNIT
    CHARACTER (LEN=*), 	INTENT(IN)	:: IOTYPE
    INTEGER,         	INTENT(IN)	:: V_LIST(:)
    INTEGER*4,		INTENT(OUT)	:: IOSTAT
    CHARACTER (LEN=*),	INTENT(INOUT)	:: IOMSG
 
    INTEGER I, J
    NAMELIST /SUBRT_NML/ I, J
 
    I=DTV%F1
    J=DTV%F2
 
    WRITE (UNIT, '(A,2I5.2)', IOSTAT=IOSTAT) IOTYPE, DTV%F1, DTV%F2
    WRITE (UNIT, NML=SUBRT_NML)
  END SUBROUTINE WRITESUBROUTINE
 
SUBROUTINE MYSUBROUTINE (DTV, UNIT, IOTYPE, V_LIST, IOSTAT, IOMSG)
    CLASS (MYDT),	INTENT(INOUT)	:: DTV
    INTEGER*4,		INTENT(IN)	:: UNIT
    CHARACTER (LEN=*), 	INTENT(IN)	:: IOTYPE
    INTEGER,         	INTENT(IN)	:: V_LIST(:)
    INTEGER*4,		INTENT(OUT)	:: IOSTAT
    CHARACTER (LEN=*),	INTENT(INOUT)	:: IOMSG
 
! X and Y are aliases for DTV%F1 and DTV%F2 since field references
! cannot be referenced in a NAMELIST statement
 
    INTEGER X, Y
    NAMELIST /SUBRT_NML/ X, Y
 
    READ (UNIT, *) DTV%F1, DTV%F2
 
    X = DTV%F1
    Y = DTV%F2
 
    READ (UNIT, NML=SUBRT_NML, IOSTAT=IOSTAT)
  
END SUBROUTINE MYSUBROUTINE

END MODULE UDIO

PROGRAM UDIO_PROGRAM
   USE UDIO
   TYPE (MYDT) :: MYDTV
   INTEGER        :: A, B
   NAMELIST /MAIN_NML/ A, MYDTV, B

   OPEN (10, FILE='udio_nml_read_write.in')
   READ (10, NML=MAIN_NML)
   WRITE (6, NML=MAIN_NML)
   CLOSE (10)
 
END PROGRAM UDIO_PROGRAM

The following shows input file 'udio_nml_read_write.in' on unit 10 read by MYSUBROUTINE:

&MAIN_NML
A=100
MYDTV=20 30
&SUBRT_NML
X=20
Y=30
/
/B=200
/

The following shows output to unit 6 by WRITESUBROUTINE:

&MAIN_NML
 A       =         100,
 MYDTV=NAMELIST   20   30
&SUBRT_NML
 I       =          20,
 J       =          30
/
 /B       =         200
/

Example 4

The following example shows user-defined derived-type UNFORMATTED input/output:


! PROGRAM: udio_unformatted_1.f90
!
! This test first writes unformatted data to a file via user-defined derived type output
! and then reads the data from the file via user-defined derived type input.
!
MODULE UNFORMATTED
    TYPE UNFORMATTED_TYPE
        INTEGER              :: I
        CHARACTER*25 :: CHAR
    CONTAINS
        PROCEDURE :: MY_UNFMT_WRITE
        GENERIC :: WRITE (UNFORMATTED) => MY_UNFMT_WRITE
    END TYPE UNFORMATTED_TYPE
 
    INTERFACE READ (UNFORMATTED)
       MODULE PROCEDURE :: MY_UNFMT_READ
    END INTERFACE
 
CONTAINS
    SUBROUTINE MY_UNFMT_WRITE (DTV, UNIT, IOSTAT, IOMSG)
        CLASS (UNFORMATTED_TYPE), INTENT(IN)    :: DTV
        INTEGER,                  INTENT(IN)    :: UNIT
        INTEGER,                  INTENT(OUT)   :: IOSTAT
        CHARACTER(LEN=*),         INTENT(INOUT) :: IOMSG 

        WRITE (UNIT=UNIT, IOSTAT=IOSTAT, IOMSG=IOMSG) DTV%I+1, DTV%CHAR
    END SUBROUTINE MY_UNFMT_WRITE
 
    SUBROUTINE MY_UNFMT_READ (DTV, UNIT, IOSTAT, IOMSG)
        CLASS (UNFORMATTED_TYPE), INTENT(INOUT)  :: DTV
        INTEGER,                  INTENT(IN)     :: UNIT
        INTEGER,                  INTENT(OUT)    :: IOSTAT
        CHARACTER (LEN=*),        INTENT(INOUT)  :: IOMSG
         
        READ (UNIT=UNIT, IOSTAT=IOSTAT, IOMSG=IOMSG) DTV%I, DTV%CHAR
        DTV%I = 1-DTV%I
    END SUBROUTINE MY_UNFMT_READ
 
END MODULE UNFORMATTED
 
PROGRAM UNFORMATTED_WRITE_PROGRAM
    USE UNFORMATTED
     
    TYPE (UNFORMATTED_TYPE) :: READ_UNFORMATTED (1,2), UNFORMATTED_OBJECT (3:3,0:1)
    INTEGER :: IOSTAT
    CHARACTER(LEN=100) :: IOMSG

    UNFORMATTED_OBJECT (3, 1) = UNFORMATTED_TYPE (I=71, CHAR='HELLO WORLD.')
    UNFORMATTED_OBJECT (3, 0) = UNFORMATTED_TYPE (I=72, CHAR='WORLD HELLO.')
 
    OPEN (UNIT=71, FILE='MYUNFORMATTED_DATA.DAT', FORM='UNFORMATTED')
    WRITE (UNIT=71) UNFORMATTED_OBJECT 
    CLOSE (UNIT=71)
 
    OPEN (UNIT=77, FILE='MYUNFORMATTED_DATA.DAT', FORM='UNFORMATTED')
    READ (UNIT=77) READ_UNFORMATTED
    CLOSE (UNIT=77)
 
    PRINT *, -READ_UNFORMATTED (:,1:2)%I .EQ. UNFORMATTED_OBJECT%I
    PRINT *, READ_UNFORMATTED%CHAR .EQ. UNFORMATTED_OBJECT%CHAR
 
END PROGRAM UNFORMATTED_WRITE_PROGRAM

The following shows output to unit * from program UNFORMATTED_WRITE_PROGRAM:

T T
 T T