使用Fortran 90正确读取输入文件中的注释行

5

据我了解,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 program test

这是“file.inp”文件:
  1 *Hello
  2 1

我使用以下技术构建了我的简单程序:

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上找不到任何信息。
3个回答

8

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

是的,我刚刚想到了这个解决方案,并且回来发布我的解决方案。但是,你的代码比我想出来的解决方案要聪明一些(我在我的读取语句中使用了“end=”选项)。不过,有一件事我不太明白,就是为什么需要使用“iso_fortran_env”?抱歉,我写过一些大型Fortran程序并让它们工作,但是当涉及到内置模块以及它们带来的好处时,我还是有点新手。 - rks171
2
除其他外,iso_fortran_env 提供了值“isostat_end”来测试非零返回代码是否为文件结尾。这允许使用“exit”构造而不是语句标签,就像“end=LineNumber”一样。 - M. S. B.

0

Fortran默认情况下不会忽略任何内容,除非您使用namelists,在这种情况下,注释以感叹号开头。


0

我发现使用backspace语句比建议的解决方案更直观。以下子程序在遇到行首注释字符"#"时跳过该行。

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)

上述实现的限制:

  1. 如果注释位于跨越多行的变量值之间,比如数组,则无法正常工作。
  2. 对于大型输入文件效率非常低,因为当遇到退格语句时,整个文件将从开头重新读取直到前一个字符。
  3. 只能用于顺序访问文件,即典型的ASCII文本文件。使用directappend访问类型打开的文件将无法正常工作。

然而,我发现它非常适合用于提供用户参数的短文件。


1
还有那句迷人的话:“禁止使用列表定向或名称列表格式删除已写入的记录。” - francescalus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接