在写格式化输出到一个变量,我得到的错误不明原因
forrtl: severe (27): too many records in I/O statement
我检查了明显的事情 - 数据是否超过了格式和长度反之亦然,变量的数量和类型与格式说明符兼容 - 我看不出为什么应该抛出错误。
的最小示例性实例是:
program TXTERR27
use iso_fortran_env, only: OUTPUT_UNIT
implicit none
double precision :: F1, F2
integer :: I1
character (len=25), parameter :: A1 = 'AaaaaAaaaaAaaaaAaaaaAaaaa'
character (len=250) :: A2
10 format(/, 'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ', I3, 'ZZZZZZZZZZZ', &
F10.3, 1X, A25, /, 'ZZZZZZZZZZZZZZZZZ', F6.3, 'ZZZZZZZZ')
20 format('Result :[', A250, ']')
continue
I1 = 1
F1 = 1.0D0
F2 = 1.0D-3
write(OUTPUT_UNIT, *) "This works:"
write(OUTPUT_UNIT, 10) I1, F1, A1, F2
write(OUTPUT_UNIT, *)
write(OUTPUT_UNIT, *) "This doesn't:"
write(A2, 10) I1, F1, A1, F2
write(OUTPUT_UNIT, 20) A2
stop
end program TXTERR27
这是通过使用编译:和没有警告或错误导致
ifort -warn all -check all -traceback -o txterr27 txterr27.f90
。输出如下:
This works:
ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 1ZZZZZZZZZZZ 1.000 AaaaaAaaaaAaaaaAaaaaAaaaa
ZZZZZZZZZZZZZZZZZ 0.001ZZZZZZZZ
This doesn't:
forrtl: severe (27): too many records in I/O statement, unit -5, file Internal Formatted Write
Image PC Routine Line Source
txterr27 000000000046EEBE Unknown Unknown Unknown
txterr27 000000000046D956 Unknown Unknown Unknown
txterr27 00000000004266A2 Unknown Unknown Unknown
txterr27 0000000000403BBB Unknown Unknown Unknown
txterr27 0000000000403122 Unknown Unknown Unknown
txterr27 0000000000419A44 Unknown Unknown Unknown
txterr27 0000000000417BFC Unknown Unknown Unknown
txterr27 0000000000402586 MAIN__ 26 txterr27.f90
txterr27 00000000004021DC Unknown Unknown Unknown
libc.so.6 00007F083D474EC5 Unknown Unknown Unknown
txterr27 00000000004020D9 Unknown Unknown Unknown
要检查是否这是一个特定编译器的问题,我重建示例代码下gfortran用:
gfortran -pedantic -Wall -fbacktrace -o txterr27 txterr27.f90
并得到了类似的结果:
This works:
ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 1ZZZZZZZZZZZ 1.000 AaaaaAaaaaAaaaaAaaaaAaaaa
ZZZZZZZZZZZZZZZZZ 0.001ZZZZZZZZ
This doesn't:
At line 26 of file txterr27.f90
Fortran runtime error: End of file
显然,格式化数据没有问题,否则写入标准输出将失败。我所能想到的是,CRLF
('/'
)导致write()
将结果呈现为数组而不是标量。将数组写入标准输出可以正常工作(每行一个条目),但如果它试图将数组写入标量,则会失败。
来自gfortran
和ifort
的错误消息有很多不足之处;道歉对已故道格拉斯亚当斯道歉:“Mostly Useless”
任何想法?
更新:继续分析,问题在于我对Fortran中“记录”的构成有何理解。下面是一个更新的说明图:
program TXTERR27A
use iso_fortran_env, only: OUTPUT_UNIT
implicit none
double precision :: F1, F2
integer :: I1
character (len=25), parameter :: A1 = 'AaaaaAaaaaAaaaaAaaaaAaaaa'
character (len=250) :: A2
character (len=250), dimension(5) :: A3
10 format(/, 'ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ', I3, 'ZZZZZZZZZZZ', &
F10.3, 1X, A25, /, 'ZZZZZZZZZZZZZZZZZ', F6.3, 'ZZZZZZZZ')
20 format('Result: [', A250, ']')
30 format('Result:', /, '[', *(A250, ']', /, '['))
continue
I1 = 1
F1 = 1.0D0
F2 = 1.0D-3
A2 = ''
A3 = ''
write(OUTPUT_UNIT, *) "This works:"
write(OUTPUT_UNIT, 10) I1, F1, A1, F2
write(OUTPUT_UNIT, *)
write(OUTPUT_UNIT, *) "Does this?"
write(A3, 10) I1, F1, A1, F2
write(OUTPUT_UNIT, 30) A3
write(OUTPUT_UNIT, *) "This doesn't:"
write(A2, 10) I1, F1, A1, F2
write(OUTPUT_UNIT, 20) A2
stop
end program TXTERR27A
这个例子表明,多个记录/串写入一个内部变量,而这个问题(为疑似)时被发射的是,write()
是试图把一个数组为标量。这是有道理的,如果你认为'/'
作为记录分隔符,而不是一个简单的CRLF
:
This works:
ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 1ZZZZZZZZZZZ 1.000 AaaaaAaaaaAaaaaAaaaaAaaaa
ZZZZZZZZZZZZZZZZZ 0.001ZZZZZZZZ
Does this?
Result:
[ ]
[ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 1ZZZZZZZZZZZ 1.000 AaaaaAaaaaAaaaaAaaaaAaaaa ]
[ZZZZZZZZZZZZZZZZZ 0.001ZZZZZZZZ ]
[ ]
[ ]
[
This doesn't:
At line 34 of file txterr27.f90
Fortran runtime error: End of file
这个问题是显而易见的,如果你牢记的Fortran I/O的古老面向记录的性质。在1969年之后开发出具有文本I/O设施的语言的长时间使用经验之后,这很容易被遗忘。对于没有看到这种情况的道歉,我们很抱歉。
无论如何,重要的一点是记住'/'
是一个记录分隔符,不要将它看作Fortran的\n
版本。
是你的人确认后刚:是的,你不能将多个记录写入内部文件? – francescalus
我想我不清楚什么是“记录”。我看到的是一个简单的字符串,但显然'/'是一个记录分隔符,而不仅仅是一个CRLF。这将解释我看到的行为。 – arclight