Fortran正在读取endfile记录之外的内容
我试图从文件中读取一些数据,endfile记录检测对于停止读取非常重要。但是,根据用于读取数据的数组的数组尺寸,我无法正确检测endfile记录,我的Fortran程序将停止 计划如下:Fortran正在读取endfile记录之外的内容,fortran,gfortran,eof,data-files,Fortran,Gfortran,Eof,Data Files,我试图从文件中读取一些数据,endfile记录检测对于停止读取非常重要。但是,根据用于读取数据的数组的数组尺寸,我无法正确检测endfile记录,我的Fortran程序将停止 计划如下: !integer, dimension(3) :: x ! line 1.1 !integer, dimension(3,10) :: x ! line 1.2 integer, dimension(10,3) ::
!integer, dimension(3) :: x ! line 1.1
!integer, dimension(3,10) :: x ! line 1.2
integer, dimension(10,3) :: ! line 1.3
integer :: status,i=1
character(len=100) :: error
open( 30, file='data.dat', status='old' )
do
print *,i
!read( 30, *, iostat=status, iomsg=error ) x ! line 2.1
!read( 30, *, iostat=status, iomsg=error ) x(:,i) ! line 2.2
read( 30, *, iostat=status, iomsg=error ) x(i,:) ! line 2.3
if ( status < 0 ) then print *,'EOF'
print *,'total of ',i-1,' lines read.'
exit
else if ( status > 0 ) then
print *,'error cod: ',status
print *,'error message: ', error
stop
else if ( status == 0 ) then
print *,'reading ok.'
i = i + 1
end if
end do
当第1.3行和第2.3行未注释时,出现所述错误:
错误代码:5008
错误消息:读取结束文件记录
但是,使用第1.1行和第2.1行,或者第1.2行和第2.2行,程序可以工作,检测结束文件记录
因此,我想了解为什么不能使用第1.3行和第2.3行正确读取此文件,因为我为read命令提供了正确的数组元素数
我正在使用gfortran编译器,版本6.3.0
编辑:更简单的示例
以下操作会产生5008“读取过去的ENDFILE记录”错误:
如果我们将
x
设为标量或一维数组(任意大小),则会得到预期的-1
EOF标志。文件实际上是否不存在或是否为空并不重要。如果文件包含一些但不够的数据,则很难理解您可能获得的返回值。我不确定是否正确表达了自己,但这与fortran读取和存储2d数组的方式有关。使用此符号时:x(:,i)
,列i
实际上是按行展开的,并且使用这一行代码读取项目。在使用x(i,:)
的另一种情况下,行i
被读取,就像您多次调用read
一样。
如果您想使用特定的形状和大小,可以使用隐含循环。例如,您可以这样使用:read(30,*,iostat=status,iomsg=error)(x(i,j),j=1,3)
在任何情况下,您都应该检查您的数据是否正确存储在变量
x
中(至少如预期的那样)。请注意,这只是一个猜测。请记住,Fortran按列主顺序存储数组。当gfortran编译read()x(:,i)
时,3个内存位置彼此相邻,因此在可执行文件中,它会生成一个对操作系统的调用,以从文件中读入3个值
现在,当编译read()x(i,:)
时,三个数据元素x(i,1)
、x(i,2)
和x(i,3)
不在连续内存中。所以我猜这个可执行文件实际上有3个对操作系统的读调用。第一个将捕获EOF,但第二个将提供文件读取结束错误
更新:我已确认Intel的ifort不会出现这种情况。gfortran以前似乎也遇到过类似的问题:。这是否是一个bug是有争议的。代码看起来确实应该捕获EOF。请在运行此程序时显示输出(工作和非工作变体)。我不清楚为什么会收到一条关于文件结束条件的消息,以便确切的输出得到澄清。第1.3行中没有“x”。这只是一个转录错误吗?很有趣。我可以用gfortran 4.8复制这个问题,但不能用ifort 16.0。我同意这是个问题。gfortran 7.2也有同样的问题。已确认(gfortran 4.8.5)。我编辑了这个问题,以显示我收到的实际信息。这显然是一个gfortran错误。您只需将第一个测试
状态设置为<0即可解决问题。或者。status==5008
为什么您希望(x(i,j),j=1,3)
与x(i,1:3)
不同?为什么使用x(i,:)
就像使用多个read语句一样?我不认为这回答了这个问题。@francescalus我同意这不应该有所不同,但我以前也遇到过这种情况。一些编译器展示了我描述的行为。我认为这并不能回答问题。名称列表输入与普通文件输入有很大不同。
10 20 30
30 40 50
implicit none
integer x(2,2),s
open(20,file='noexist')
read(20,*,iostat=s)x
write(*,*)s
end