【问题标题】:Can I read the rest of the line after a positive value of IOSTAT?我可以在 IOSTAT 为正值后读取该行的其余部分吗?
【发布时间】:2015-05-16 19:56:42
【问题描述】:

我有一个包含 13 列和 41 行的文件,其中包含 41 个不同组的 Joback Method 的系数。但是,有些值是不存在的,表格将它们列为“X”。我将表格保存为 .csv,并在我的代码中将文件读取到数组中。 .csv 中两行的摘录(第二行包含不存在的系数)如下所示:

48.84,11.74,0.0169,0.0074,9.0,123.34,163.16,453.0,1124.0,-31.1,0.227,-0.00032,0.000000146
X,74.6,0.0255,-0.0099,X,23.61,X,797.0,X,X,X,X,X 

我尝试做的是读取并定义一个数组来保存每个 IOSTAT 值,这样我就可以知道是否读取了“X”(即 IOSTAT 为正):

DO I = 1, 41
        (READ(25,*,IOSTAT=ReadStatus(I,J)) JobackCoeff, J = 1, 13)
END DO

我发现的问题是,如果要读取的行的第一个值是“X”,产生 ReadStatus 的正值,那么这些行的其余值不会被正确读取。

如果 JobackCoeff(I,J) 导致读取错误,我的意图是使用 ReadStatus 数组生成错误消息,从而精确定位“X”。

出现读取错误后,我可以强制程序继续读取一行吗?或者有更好的方法吗?

【问题讨论】:

    标签: csv file-io fortran


    【解决方案1】:

    一旦在输入执行期间发生错误,输入列表的处理就会终止。此外,输入列表中指定的所有变量都未定义。对您的第一个问题的简短回答是:不,在读取错误后无法继续读取一行。

    然后,当需要更复杂的输入处理时,我们会得到通常的答案:将行读入字符变量并进行处理。我不会为您编写完整的代码(主要是因为不清楚确切需要什么),但是当您有一个字符变量时,您可能会发现 index 内在函数很有用。有了它,您可以找到Xs(重复调用子字符串以在一行中找到所有子字符串)。

    或者,如果您提供一个明确的格式(而不是依赖于列表导向的 (fmt=*) 输入),您也许可以使用非高级输入(read 语句中的advance='no')来做一些事情。但是,一旦出现错误情况,文件的位置就会变得不确定:您还必须处理这个问题。将行作为字符变量进行处理可能要简单得多。

    下面给出了概念的概要(没有声明,稳健性)。

    read(iunit, '(A)') line
    idx = 1    
    do i=1, 13
      read(line(idx:), *, iostat=iostat) x(i)
      if (iostat.gt.0) then
        print '("Column ",I0," has an X")', i
        x(i) = -HUGE(0.)  ! Recall x(i) was left undefined
      end if
      idx = idx + INDEX(line(idx:), ',')
    end do     
    

    【讨论】:

    • 所以如果我理解正确,你是在建议我将所有行都作为字符读取然后解析它们?
    • 是的。如果除了检测是否发生错误之外,您还想做其他事情,则需要进行一些额外的处理。幸运的是,这并不太棘手,正如我的示例所希望显示的那样。
    【解决方案2】:

    许多 Fortran 程序员和其他语言的程序员长期使用的替代方法是使用某种编辑器(我喜欢 sed)并通过将所有 Xs 更改为 @ 来修改文件987654323@s。您的编译器必须提供对IEEE NaNs 的支持才能使其工作(当前广泛使用的大多数作物都可以)并且它们会将输入文件中的NAN 正确解释为值为NaN 的实数。

    与已经接受的(并且非常好的)答案相比,这种方法的好处是不需要在 Fortran 中进行巧妙的编程来解析包含混合条目的输入行。使用编辑器处理字符串,使用 Fortran 读取数字。

    【讨论】:

    • 感谢您的建议,以后一定会派上用场的。然而,在这种情况下,我实际上使用子程序中存在读取错误的事实来通知用户某个值不可用。我可以通过检查读取的值是否为 NaN 来做类似的事情吗?看到变量是真实的,这是否可能?
    • 有一个 Fortran 内在函数 ieee_is_nan 用于测试值的 nan-ness。
    • 我明白了。猜猜那将是一个更简单的解决方案。谢谢
    猜你喜欢
    • 2021-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-08
    • 2022-11-25
    • 2021-12-22
    • 1970-01-01
    相关资源
    最近更新 更多