如何知道我们在 Fortran 77 中到达了 EOF?
How to know that we reached EOF in Fortran 77?
所以让我们假设我有以下子例程:
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
它只从文件中读取一行。但我想递归地阅读所有行。因此,当我在主程序中递归调用子程序时,在到达 EOF 后出现错误。那么有没有办法阻止它让程序知道我什么时候到达EOF?
基本上,我想知道什么时候到达EOF。
在 Fortran 77 中,您使用 END=label
specifier,它指示程序在触发文件结束条件时转到给定的 label
。基本上它的工作方式类似于由 READ
语句触发的 GO TO
语句。
在 Fortran 90 及更高版本中,您还可以使用 IOSTAT=integer_var
说明符。如果发生错误情况,integer_var
将为正数,如果发生 end-of-record
(EOR) 或 end-of-file
(EOF) 情况,则该值为负数。
在 Fortran 2003 中,可以在命名常量中找出 EOR 和 EOF 条件的实际值,如 Ian Bush 的答案所示。
这里有两种方法。我拒绝教授过时的 Fortran 77,它在 25 年以上不应该被使用或教授,但第一种方法应该适用于从 77 开始的任何版本的 Fortran
方法一:
ijb@ianbushdesktop ~/Whosebug $ cat data.dat
1
2
3
ijb@ianbushdesktop ~/Whosebug $ 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 ~/Whosebug $ gfortran -std=f2003 -Wall -Wextra -O -fcheck=all end.f90
ijb@ianbushdesktop ~/Whosebug $ ./a.out
1
2
3
Hit EOF
方法二:
这需要 F2003,但这是您现在应该使用的
ijb@ianbushdesktop ~/Whosebug $ cat data.dat
1
2
3
ijb@ianbushdesktop ~/Whosebug $ 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 ~/Whosebug $ gfortran -std=f2003 -Wall -Wextra -O -fcheck=all end2.f90
ijb@ianbushdesktop ~/Whosebug $ ./a.out
1
2
3
Hit EOF
所以让我们假设我有以下子例程:
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
它只从文件中读取一行。但我想递归地阅读所有行。因此,当我在主程序中递归调用子程序时,在到达 EOF 后出现错误。那么有没有办法阻止它让程序知道我什么时候到达EOF? 基本上,我想知道什么时候到达EOF。
在 Fortran 77 中,您使用 END=label
specifier,它指示程序在触发文件结束条件时转到给定的 label
。基本上它的工作方式类似于由 READ
语句触发的 GO TO
语句。
在 Fortran 90 及更高版本中,您还可以使用 IOSTAT=integer_var
说明符。如果发生错误情况,integer_var
将为正数,如果发生 end-of-record
(EOR) 或 end-of-file
(EOF) 情况,则该值为负数。
在 Fortran 2003 中,可以在命名常量中找出 EOR 和 EOF 条件的实际值,如 Ian Bush 的答案所示。
这里有两种方法。我拒绝教授过时的 Fortran 77,它在 25 年以上不应该被使用或教授,但第一种方法应该适用于从 77 开始的任何版本的 Fortran
方法一:
ijb@ianbushdesktop ~/Whosebug $ cat data.dat
1
2
3
ijb@ianbushdesktop ~/Whosebug $ 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 ~/Whosebug $ gfortran -std=f2003 -Wall -Wextra -O -fcheck=all end.f90
ijb@ianbushdesktop ~/Whosebug $ ./a.out
1
2
3
Hit EOF
方法二:
这需要 F2003,但这是您现在应该使用的
ijb@ianbushdesktop ~/Whosebug $ cat data.dat
1
2
3
ijb@ianbushdesktop ~/Whosebug $ 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 ~/Whosebug $ gfortran -std=f2003 -Wall -Wextra -O -fcheck=all end2.f90
ijb@ianbushdesktop ~/Whosebug $ ./a.out
1
2
3
Hit EOF