nor*_*rio 6 io file-io standards fortran
你知道以下声明是否可以通过fortran 90/95/2003标准之一保证真实吗?"假设一个字符变量的read语句被赋予一个空行(即只包含空格和换行符号).如果格式说明符是星号(*),它继续读取后续行,直到非空白如果格式说明符为'(A)',则将空字符串替换为字符变量."
例如,请查看以下最小程序和输入文件.
程序代码:
PROGRAM chk_read
INTEGER, PARAMETER :: MAXLEN=30
CHARACTER(len=MAXLEN) :: str1, str2
str1='minomonta'
read(*,*) str1
write(*,'(3A)') 'str1_start|', str1, '|str1_end'
str2='minomonta'
read(*,'(A)') str2
write(*,'(3A)') 'str2_start|', str2, '|str2_end'
END PROGRAM chk_read
Run Code Online (Sandbox Code Playgroud)
输入文件:
----'input.dat' content is below this line----
yamanakako
kawaguchiko
----'input.dat' content is above this line----
Run Code Online (Sandbox Code Playgroud)
请注意,'input.dat'中有四行,第一行和第三行是空白的(仅包含空格和换行符).如果我运行程序为
$ ../chk_read < input.dat > output.dat
Run Code Online (Sandbox Code Playgroud)
我得到以下输出
----'output.dat' content is below this line----
str1_start|yamanakako |str1_end
str2_start| |str2_end
----'output.dat' content is above this line----
Run Code Online (Sandbox Code Playgroud)
变量'str1'的第一个读语句似乎是查看'input.dat'的第一行,找到一个空行,移到第二行,找到字符值'yamanakako',并将其存储在'str1'中".
相反,变量'str2'的第二个read语句似乎给出了第三行,它是空白的,并将空行存储在'str2'中,而不是移到第四行.
我尝试用英特尔Fortran(ifort 12.0.4)和GNU Fortran(gfortran 4.5.0)编译程序并得到相同的结果.
稍微讨论一下这个问题的背景:我正在编写一个子程序来读取一个使用空行作为数据块分隔符的数据文件.我想确保在读取数据时丢弃空白行,只留下空白行.我还需要使其标准符合和便携.
谢谢你的帮助.
来自 Fortran 2008 标准草案:
列表定向输入/输出允许根据列表项的类型而不是格式规范来编辑数据。它还允许数据自由字段,即用逗号(或分号)或空格分隔。
然后:
一个或多个列表定向记录中的字符构成一系列值和值分隔符。记录结尾与空白字符具有相同的效果,除非它位于字符常量内。任何两个或多个连续空格的序列都被视为单个空格,除非它位于字符常量内。
这隐含地表明,在列表定向输入中,空行被视为空白,直到下一个非空白值。
读取时使用fmt='(A)'格式描述符时,空行被读入str。另一方面,fmt=*(表示自由格式的列表定向 I/O)会跳过空白行,直到找到非空白字符串。要测试这一点,请执行以下操作:
PROGRAM chk_read
INTEGER :: cnt
INTEGER, PARAMETER :: MAXLEN=30
CHARACTER(len=MAXLEN) :: str
cnt=1
do
read(*,fmt='(A)',end=100)str
write(*,'(I1,3A)')cnt,' str_start|', str, '|str_end'
cnt=cnt+1
enddo
100 continue
END PROGRAM chk_read
$ cat input.dat
yamanakako
kawaguchiko
Run Code Online (Sandbox Code Playgroud)
EOF
运行程序给出以下输出:
$ a.out < input.dat
1 str_start| |str_end
2 str_start| |str_end
3 str_start| |str_end
4 str_start|yamanakako |str_end
5 str_start| |str_end
6 str_start|kawaguchiko |str_end
Run Code Online (Sandbox Code Playgroud)
另一方面,如果您使用默认输入:
read(*,fmt=*,end=100)str
Run Code Online (Sandbox Code Playgroud)
您最终会得到以下输出:
$ a.out < input.dat
1 str1_start|yamanakako |str1_end
2 str2_start|kawaguchiko |str2_end
Run Code Online (Sandbox Code Playgroud)