保存变量时记录结束错误

End of Record error when saving a variable

当我 运行 使用另一台计算机可以正常工作的代码时,我遇到了 运行 时间错误。

我想知道是不是这台机器的Fortran编译器(GCC 4.9.2)的问题,因为以前的电脑用的是以前的版本

像这样定义变量时出现问题:

在我定义的模块中

character(30),allocatable,save :: sceneclass(:)

然后子程序中sceneclass根据

定义
character(30) surf, frac, scene

allocate(sceneclass(10)) 

do i=1,10
write(sceneclass(i),*) trim(scene)//trim(surf)//'_'//trim(frac)
enddo

在第一次迭代中我得到 "End of record"。但我不知道问题出在哪里。它似乎在其他计算机上工作正常。

您可能正在向 sceneclass(i) 写入一个比您指定的 30 个字符更长的字符串。

我可以用

重现这个
program test
  implicit none
  character(10),allocatable :: sceneclass(:)
  integer                   :: i

  allocate( sceneclass(10) ) 

  do i=1,10
    write(sceneclass(i),*) 10**i
  enddo

  print *, ( trim(sceneclass(i)), i=1,10 )

end program

gfortran 失败

Fortran runtime error: End of record

ifort正确报错:

output statement overflows record, unit -5, file Internal List-Directed Write

将字符串长度增加到 12 可以解决这种情况下的问题。您可以(并且应该)在 write 语句中使用 iostat 来捕获它。

需要注意的一点是,当你指定一个列表定向*写入一个字符串时,编译器总是(?)添加一个额外的前导空白,所以字符串的有效长度你可以write 比你想象的少了一个。

要解决这个问题(当然假设您无论如何都不想要前导空白)使用字符串编辑描述符:

   write(sceneclass(i),'(a)')...

有趣的是ifort (linux 11.1)居然允许你超限一个字符:

 character*5 c
 write(c,*)'12345'  ! result: " 1234"

我认为这是一个错误。似乎他们也忘记了计算空白..(gfortran 抛出上述错误,如果你再添加一个字符,ifort 会犹豫)

如果你想知道为什么空白.. Are Fortran control characters (carriage control) still implemented in compilers?

请看这里

现在我很好奇某个地方的某些编译器是否没有为内部列表写入执行此操作,或者您的代码之前可能使用标志编译以禁用 "printer control" 代码