Search code examples
iofortranreadfilefortran77

How to know that we reached EOF in Fortran 77?


So let's assume that I have the following subroutine:

         subroutine foo(a_date)
         character*10 dummy, a_date
         open(unit=1,file='ifile.txt',status='old')
         read(1, 100) dummy
   100   format(A10)
         a_date = dummy
         return
         end

which only reads a line from the file. But I want to read all the lines recursively. So when I call the subroutine recursively in my main procedure, I get an error after reaching EOF. So is there a way to prevent it so that the program knows when I reach EOF? Basically, I want to be able to know when I reach EOF.


Solution

  • Here are two methods. I refuse to teach the obsolete Fortran 77 which shouldn't have been used or taught in 25 years+, but the first method should work in any version of Fortran from 77 onwards

    Method 1:

    ijb@ianbushdesktop ~/stackoverflow $ cat data.dat 
    1
    2
    3
    ijb@ianbushdesktop ~/stackoverflow $ cat end.f90
    Program eof
      Implicit None
      Integer :: data
      Open( 10, file = 'data.dat' )
      Do
         Read( 10, *, End = 1 ) data
         Write( *, * ) data
      End Do
    1 Write( *, * ) 'Hit EOF'
    End Program eof
    ijb@ianbushdesktop ~/stackoverflow $ gfortran -std=f2003 -Wall -Wextra -O -fcheck=all end.f90 
    ijb@ianbushdesktop ~/stackoverflow $ ./a.out
               1
               2
               3
     Hit EOF
    

    Method 2:

    This needs F2003, but that's what you should be using these days

    ijb@ianbushdesktop ~/stackoverflow $ cat data.dat 
    1
    2
    3
    ijb@ianbushdesktop ~/stackoverflow $ cat end2.f90
    Program eof
      Use, intrinsic :: iso_fortran_env, Only : iostat_end
      Implicit None
      Integer :: data, error
      Open( 10, file = 'data.dat' )
      Do
         Read( 10, *, iostat = error ) data
         Select Case( error )
         Case( 0 )
            Write( *, * ) data
         Case( iostat_end )
            Exit
         Case Default
            Write( *, * ) 'Error in reading file'
            Stop
         End Select
      End Do
      Write( *, * ) 'Hit EOF'
    End Program eof
    ijb@ianbushdesktop ~/stackoverflow $ gfortran -std=f2003 -Wall -Wextra -O -fcheck=all end2.f90 
    ijb@ianbushdesktop ~/stackoverflow $ ./a.out
               1
               2
               3
     Hit EOF