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

时间:2012-04-21 14:20:18

标签: 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 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正确解释该注释行似乎是一个问题。它必须是非常简单的东西,我在这里失踪,但我无法在谷歌上找到任何东西。

3 个答案:

答案 0 :(得分:7)

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

答案 1 :(得分:0)

默认情况下Fortran不会忽略任何内容,除非您使用名单,并且在这种情况下,评论以感叹号开头。

答案 2 :(得分: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. 对于大型输入文件,这是非常低效的,因为在遇到Backspace语句时会从头开始直到前一个字符重新读取整个文件。
  3. 只能用于sequential访问文件,即典型的ASCII文本文件。使用directappend访问类型打开的文件将不起作用。

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