在寫格式化輸出到一個變量,我得到的錯誤不明原因
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