[J3] Interaction between user-defined input and list-directed input

Thomas König tk at tkoenig.net
Sun Apr 24 10:07:51 UTC 2022


Hello,

I have been having some trouble understanding the interaction between
the particular features of list-directed input and user-defined
input.

One point: Input of the form r*c.  I see no mention in the standard of
this being restricted in the case of user-defined I/O, so I would
expect the test program

module x
   implicit none
   type foo
      real :: r
   end type foo
   interface read(formatted)
      module procedure read_formatted
   end interface read(formatted)
contains
   subroutine read_formatted (dtv, unit, iotype, vlist, iostat, iomsg)
     class (foo), intent(inout) :: dtv
     integer, intent(in) :: unit
     character (len=*), intent(in) :: iotype
     integer, intent(in) :: vlist(:)
     integer, intent(out) :: iostat
     character (len=*), intent(inout) :: iomsg
     read (unit,*,iostat=iostat,iomsg=iomsg) dtv%r
   end subroutine read_formatted
end module x

program main
   use x
   implicit none
   type(foo) :: a, b
   open (10,status="scratch")
   write (10,'(A)') '2*1.0'
   rewind (10)
   read (10,*) a%r, b%r
   print *,a,b
   rewind (10)
   a%r = -42.
   b%r = -42.
   read (10,*) a, b
   print *,a,b
end program main

to succeed and to print something like

    1.00000000       1.00000000
    1.00000000       1.00000000

Another point is the handling of when an item has been read.
Is the child I/O responsible for reading records? Looking
at

module x
   implicit none
   type, public:: foo
      character(len=2) :: c
   end type foo
   interface read(formatted)
      module procedure read_formatted
   end interface read(formatted)
contains
   subroutine read_formatted (dtv, unit, iotype, vlist, iostat, iomsg)
     class (foo), intent(inout) :: dtv
     integer, intent(in) :: unit
     character (len=*), intent(in) :: iotype
     integer, intent(in) :: vlist(:)
     integer, intent(out) :: iostat
     character (len=*), intent(inout) :: iomsg
     read (unit,'(A)',iostat=iostat,iomsg=iomsg) dtv%c
   end subroutine read_formatted
end module x

program main
   use x
   implicit none
   type(foo) :: a, b
   open (10,file="testfile.dat",status="replace")
   write (10,'(A)') '','aa bb'
   rewind (10)
   read (10,*) a%c, b%c
   write (*,'(10(A))') "Component read   : a = '",a,"' , b = '", b, "'"
   rewind (10)
   a%c = "x"
   b%c = "y"
   read (10,*) a, b
   write (*,'(10(A))') "User-defined read: a = '",a,"' , b = '", b, "'"
end program main

I get output of

Component read   : a = 'aa' , b = 'bb'
User-defined read: a = 'aa' , b = 'bb'

or

Component read   : a = 'aa' , b = 'bb'
User-defined read: a = '  ' , b = '  '

depending on which compiler I use.

Finally, the question of when a value is actually read is
a bit unclear.  Is the child I/O responsible for reading
until end of record or a space?  Test case is

module x
   implicit none
   type, public:: foo
      character :: c
   end type foo
   interface read(formatted)
      module procedure read_formatted
   end interface read(formatted)
contains
   subroutine read_formatted (dtv, unit, iotype, vlist, iostat, iomsg)
     class (foo), intent(inout) :: dtv
     integer, intent(in) :: unit
     character (len=*), intent(in) :: iotype
     integer, intent(in) :: vlist(:)
     integer, intent(out) :: iostat
     character (len=*), intent(inout) :: iomsg
     read (unit,'(A)',iostat=iostat,iomsg=iomsg) dtv%c
   end subroutine read_formatted
end module x

program main
   use x
   implicit none
   type(foo) :: a, b
   open (10,file="testfile.dat",status="replace")
   write (10,'(A)') 'aa bb'
   rewind (10)
   read (10,*) a%c, b%c
   write (*,'(10(A))') "Component read   : a = '",a,"' , b = '", b, "'"
   rewind (10)
   a%c = "x"
   b%c = "y"
   read (10,*) a, b
   write (*,'(10(A))') "User-defined read: a = '",a,"' , b = '", b, "'"
end program main

where at least there is agreement between compilers, i.e.

Component read   : a = 'a' , b = 'b'
User-defined read: a = 'a' , b = 'a'

Best regards

	Thomas


More information about the J3 mailing list