【问题标题】:Fortran read input into dynamic arrayFortran 将输入读入动态数组
【发布时间】:2023-03-27 10:14:02
【问题描述】:

我想从输入文件中读取坐标。示例输入文件如下所示:

1    0.1542    0.2541    1.2451   N
12   4.5123    2.0014    2.0154   O
43   8.2145    0.2978    4.2165   H

etc... 这个文件的大小是可变的。第一列是分配给原子的数字,以下列是它的 x、y、z 坐标,最后一列是原子的元素符号。

我尝试了一些类似的方法:

integer, allocatable :: atnum(:)
double precision, allocatable :: coord(:,:)
character(len=2), allocatable :: element(:)

open(unit=20, file='input', status='old',action='read')

read(20,*,end=200) atnum, coord(:,1:3), element
200 close(20)

这会引发错误:

Fortran runtime error: Bad integer for item 2 in list input

我假设程序将第一个条目读入atnum(1),但随后尝试继续将第一行的第二个条目读入atnum(2)。如何让它正确读取输入?

我还认为告诉程序将中间三列读入coord(:,1:3) 可能有问题。它很可能会将前三个条目读入coord(1,1), coord(2,1), coord(3,1),然后遇到行尾的字符并再次变得混乱。我如何告诉它修复该行的第一个下标,并读入另一个维度?还是我必须交换索引,例如coord(1:3,:)?这行得通吗?

编辑:以上已由 tpg2114 回答,但我仍有问题。在我知道要读取多少组坐标之前,我无法分配数组,但我只知道在到达文件末尾之前有多少原子。如果我不分配atnum, coord and element,程序编译得很好,但是当我尝试运行它时会返回一个分段错误。如何在不预先分配动态数组的情况下将其读入?

听起来类似于这个问题:Variable size arrays in Fortran without Allocate()

提前致谢。

【问题讨论】:

    标签: fortran


    【解决方案1】:

    您需要遍历 READ 语句。单个 READ 只会转到记录的末尾,在这种情况下是行。你会知道什么时候用完行,因为你放了 end=200 参数,所以它会跳到第 200 行(你在这里似乎没有)。

    所以,你需要确保:

    A)您的数组足够长以包含文件(您没有显示它们的分配,我假设您分配了它们?)

    B) 你遍历 READ 语句

    C) 你为 atnum 参数和 coord 的第一个参数和 elem 参数指定一个索引。

    例如,假设声明相同并且数组分配的足够大,并且 I 是一个 INTEGER

    I = 1
    DO 
      read(20,*,end=200) atnum(I), coord(I,1:3), elem(I)
      I = I + 1
    END DO 
    200 continue
    

    此外,请考虑删除 end=200 部分并改用 IOSTAT,因为它是现代的并且不推荐使用行号。

    【讨论】:

    • 感谢您的回答。我不确定如何实现读取数据do 循环。你是说我应该有类似k=iostat 的东西而不是end=200 并有像do while (k .ge. 0) ... end do 这样的循环?那行得通吗?
    • 阅读 cs.mtu.edu/~shene/COURSES/cs201/NOTES/chap04/iostatus.html 了解 IOSTAT 的工作原理。
    【解决方案2】:

    步骤1:读取文件,将每一行读入一个字符串,仅将行数计为“num_lines”,使用“iostat”检测文件结束条件。

    第 2 步:倒回文件。

    第 3 步:将数组分配到正确的长度“num_lines”。

    第 4 步:将文件“实际”读取到数组中,逐个元素:

    do i=1, num_lines
       read (20, *) atnum(I), coord(I,1:3), elem(I)
    end do
    

    【讨论】:

    • 这就是我所担心的。两次读取同一个文件。似乎是唯一的方法。我将如何“倒带”文件?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-19
    • 2016-03-19
    • 2016-04-25
    • 1970-01-01
    • 1970-01-01
    • 2018-03-01
    相关资源
    最近更新 更多