Fortran正在读取endfile记录之外的内容

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Fortran正在读取endfile记录之外的内容相关的知识,希望对你有一定的参考价值。

我正在尝试从文件中读取一些数据,并且结束文件记录检测对于停止读取非常重要。但是,根据用于读取数据的数组的数组维度,我无法正确检测到endfile记录,并且我的Fortran程序停止。

该计划如下:

!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

使用'data.dat'文件:

10 20 30
30 40 50

当取消注释第1.3和2.3行时,会出现上述错误:

错误代码:5008

错误消息:读取过去的ENDFILE记录

但是,使用第1.1和2.1行,或1.2和2.2,程序可以正常工作,检测结束文件记录。

所以,我想帮助理解为什么我不能使用1.3和2.3行来正确读取这个文件,因为我给了read命令正确数量的数组元素。

我正在使用gfortran编译器,版本6.3.0。

编辑:更简单的例子

以下产生5008“读取过去的ENDFILE记录”错误:

implicit none
integer x(2,2),s
open(20,file='noexist')
read(20,*,iostat=s)x
write(*,*)s
end

如果我们使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,但第二个会给你读取文件错误的结尾。

更新:我已经确认英特尔的ifort不会发生这种情况。 gfortran之前似乎遇到过类似的问题:Bad IOSTAT values when readings NAMELISTs past EOF。这是否是一个错误是值得商榷的。代码肯定看起来应该陷入EOF。

以上是关于Fortran正在读取endfile记录之外的内容的主要内容,如果未能解决你的问题,请参考以下文章

Fortran 无法从文件中读取

从fortran文件中读取变量

在 Fortran 中逐行读取逗号分隔的文本文件

从 txt (Fortran) 中错误读取变量

如何在 Fortran 程序中读取 .raw 文件?

fortran如何读入文本文件中的某行的指定部分