File io 使用Fortran 90正确读取输入文件中的注释行
据我所知,Fortran在从文件中读取数据时,会跳过以和星号(*)开头的行,假设它们是注释。嗯,我似乎在用我创建的一个非常简单的程序实现这种行为时遇到了问题。这是我的简单Fortran程序:File io 使用Fortran 90正确读取输入文件中的注释行,file-io,comments,fortran,gfortran,File Io,Comments,Fortran,Gfortran,据我所知,Fortran在从文件中读取数据时,会跳过以和星号(*)开头的行,假设它们是注释。嗯,我似乎在用我创建的一个非常简单的程序实现这种行为时遇到了问题。这是我的简单Fortran程序: 1 program test 2 3 integer dat1 4 5 open(unit=1,file="file.inp") 6 7 read(1,*) dat1 8 9 10 end progr
1 program test
2
3 integer dat1
4
5 open(unit=1,file="file.inp")
6
7 read(1,*) dat1
8
9
10 end program test
这是“file.inp”:
我用
gfortran -g -o test test.f90
当我运行时,我得到一个错误:
At line 7 of file test.f90 (unit = 1, file = 'file.inp')
Fortran runtime error: Bad integer for item 1 in list input
当我在删除注释行的情况下运行输入文件时,即:
1 1
代码运行良好。因此,Fortran正确解释注释行似乎有问题。这肯定是我在这里遗漏的非常简单的东西,但我在google上找不到任何东西。Fortran不会自动跳过输入文件中的注释行。通过首先将该行读入字符串,检查注释符号的第一个字符或搜索该符号的字符串,然后如果该行不是注释,则对该字符串进行“内部读取”以获得数值,可以非常轻松地完成此操作 比如:
use, intrinsic :: iso_fortran_env
character (len=200) :: line
integer :: dat1, RetCode
read_loop: do
read (1, '(A)', isostat=RetCode) line
if ( RetCode == iostat_end) exit ReadLoop
if ( RetCode /= 0 ) then
... read error
exit read_loop
end if
if ( index (line, "*") /= 0 ) cycle read_loop
read (line, *) dat1
end do read_loop
Fortran默认情况下不会忽略任何内容,除非您使用的是名称列表,在这种情况下,注释以感叹号开头。我发现使用该语句比建议的解决方案更直观。当在行首遇到注释字符“#”时,以下子例程跳过该行
subroutine skip_comments(fileUnit)
integer, intent(in) :: fileUnit
character(len=1) :: firstChar
firstChar = '#'
do while (firstChar .eq. '#')
read(fileUnit, '(A)') firstChar
enddo
backspace(fileUnit)
end subroutine skip_comments
此子例程可在read
语句之前的程序中使用,如下所示:
open(unit=10, file=filename)
call skip_comments(10)
read(10, *) a, b, c
call skip_comments(10)
read(10, *) d, e
close(10)
上述实施的限制:
顺序
访问文件,即典型的ASCII文本文件。使用direct
或append
访问类型打开的文件将不起作用然而,我发现它非常适合用于提供用户参数的短文件。是的,我刚刚发现了这一点,实际上,我正在回来发布我的解决方案。但是,您的代码比我提出的解决方案要聪明一点(我在read语句中使用了“end=”选项)。但有一件事我不明白,那就是使用“iso_fortran_env”有什么必要?很抱歉,我已经编写了一些大型Fortran程序并使其正常工作,但对于内部模块以及它们给表带来的内容,我有点不知所措。除此之外,iso_Fortran_env提供了值“isostat_end”,以测试非零返回代码是否是文件的结尾。这允许使用“exit”构造而不是语句标签,就像“end=LineNumber”一样。我们不要忘记迷人的“禁止对使用列表定向或名称列表格式编写的记录进行退格”
open(unit=10, file=filename)
call skip_comments(10)
read(10, *) a, b, c
call skip_comments(10)
read(10, *) d, e
close(10)