Fortran 无法从文件中读取

Posted

技术标签:

【中文标题】Fortran 无法从文件中读取【英文标题】:Fortran can't read from file 【发布时间】:2020-04-07 16:34:13 【问题描述】:

我正在尝试从使用 Fortran 创建的 txt 文件中读取多个变量。文件的行数是随机的,每行上写的数字也是随机的。

文件看起来像这样:

1061    2.5   5.0    7.5    3.5
1062    9.0   2.5   10.0    7.5 

然后我在一个单独的 Fortran 程序上打开该文件并尝试从中读取。

我的代码看起来像这样,ainteger,而 bcdef 都是真实值:

    open(10,file='data.txt',form='unformatted')
    do
        read(10,*,iostat=st) a,b,c,d,e
        if(st==-1) exit 
        f=a+b+c+d+e
    end do

当我尝试运行程序时,出现运行时错误,告诉我我指的是未定义的变量,当我尝试运行调试器时,变量abc、@987654335 @ 和 e 即使在读取命令之后也保持未定义。

【问题讨论】:

请提供Minimal, Reproducible Example。尝试关闭iostat,看看是否有运行时错误——我猜是有。 请在edit问题中包含abcde的定义。 稍微扩展@SteveLionel 的评论 iostat 保证成功时为0,如果出现问题,则保证为另一个值(不一定为-1)。检查它为 -1 几乎肯定不会捕获所有可能的错误,如果发生错误,a、b、c、d 和 e 将是未定义的。 所以请听从@SteveLionel 他的建议并提供MWE!否则它会一直盯着水晶球。 character(len=80) msg 添加到您的声明中。您确实已正确声明了所有内容,对吗?然后将iomsg=msg添加到read语句中,然后打印出msg。如果代码没有超过第一行,那么这表明您在第一行中有一个不可打印的字符,导致读短。 【参考方案1】:

只需总结 cmets 和现有答案,您应该删除 'unformatted' 关键字在 open 语句中,因为 fortran 读取文本文件 作为您的data.txt 默认格式为一个。

假设您的文本文件可能如下所示:

1061    2.5   5.0    7.5    3.5
1062    9.0   2.5   10.0    7.5
1063    4.0   3.1    3.2    5  
1064    2.1   1.9  *****    7.8
1065    1.0   4.0   10.0    3.5
1066    4.4   1.9    2.5
1067    6.7   8.8   10.9   12.0

那么您应该在此之后处理不同的格式错误 最小的例子:

program FileIO
implicit none
character(256) :: line
character(80)  :: msg
integer :: a,st
real :: b,c,d,e,f

open(10,file='data.txt')
do
    write(*,'(A)') '------------------------------------------------------------'
    read(10,'(A)',iostat=st) line                 ! Buffer input in line
    write(*,'(A)') 'Reading of line '//trim(line)
    if (st < 0) then                              ! End of file or end of record
        exit
    else
        read(line,*,iostat=st,iomsg=msg) a,b,c,d,e
        write(*,'(A)') 'IO-message is: '//trim(msg)
        if (st == 0) then                         ! Read one line successfully
            write(*,'(A)') 'Line successfully read: '//trim(line)
            f=a+b+c+d+e                           ! Calculate result
        else
            write(*,'(A)') 'IO-error occured in line: '//trim(line)
            f=0
        endif
    endif
end do
close(10)

end program FileIO

iostat 的否定结果表示文件结束或记录结束事件。 iostat 的肯定结果表示运行时错误消息,请参见例如对于Intel Fortran。

这应该由if 条件处理。

我建议您将文件输入缓冲在字符变量中,例如line。 它可以帮助您将错误生成行写回日志文件或标准 输出。

最小的例子生成这个输出:

------------------------------------------------------------
Reading of line 1061    2.5   5.0    7.5    3.5
IO-message is:                                                                  
Line successfully read: 1061    2.5   5.0    7.5    3.5
------------------------------------------------------------
Reading of line 1062    9.0   2.5   10.0    7.5
IO-message is:                                                                  
Line successfully read: 1062    9.0   2.5   10.0    7.5
------------------------------------------------------------
Reading of line 1063    4.0   3.1    3.2    5
IO-message is:                                                                  
Line successfully read: 1063    4.0   3.1    3.2    5
------------------------------------------------------------
Reading of line 1064    2.1   1.9  *****    7.8
IO-message is: list-directed I/O syntax error, unit -5, file Internal List-Directed Read
IO-error occured in line: 1064    2.1   1.9  *****    7.8
------------------------------------------------------------
Reading of line 1065    1.0   4.0   10.0    3.5
IO-message is: list-directed I/O syntax error, unit -5, file Internal List-Directed Read
Line successfully read: 1065    1.0   4.0   10.0    3.5
------------------------------------------------------------
Reading of line 1066    4.4   1.9    2.5
IO-message is: end-of-file during read, unit -5, file Internal List-Directed Read
IO-error occured in line: 1066    4.4   1.9    2.5
------------------------------------------------------------
Reading of line 1067    6.7   8.8   10.9   12.0
IO-message is: end-of-file during read, unit -5, file Internal List-Directed Read
Line successfully read: 1067    6.7   8.8   10.9   12.0
------------------------------------------------------------
Reading of line 1067    6.7   8.8   10.9   12.0

第 1063 行的列表导向读取工作正常,即使数字 5 是 以整数形式提供给实变量e。行格式错误***** 正确检测到 1064 以及第 1066 行中缺少的数字。

请查看有关list-directed reading 的英特尔 Fortran 帮助, 如果您需要更多信息。

希望对你有帮助。

【讨论】:

【参考方案2】:

在我看来,您的文件是格式化文件(实际上您使用* 作为格式)。但是,您在 open 语句中将其定义为 'unformatted'。尝试设置

form='formatted'

在您的 open 语句中,或者只是省略 form= 子句,因为默认是格式化的。

【讨论】:

以上是关于Fortran 无法从文件中读取的主要内容,如果未能解决你的问题,请参考以下文章

fortran读取一行数据

从fortran文件中读取变量

Fortran正在读取endfile记录之外的内容

在 Fortran 中读取浮点数时出错

将工作代码从双精度转换为四精度:如何从输入文件中读取 FORTRAN 中的四精度数字

从 txt (Fortran) 中错误读取变量