Fortran将输入读入动态数组

时间:2011-12-15 23:12:24

标签: fortran

我想从输入文件中读取坐标。示例输入文件类似于:

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

等...此文件的大小是可变的。第一列是分配给原子的数字,以下列是其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()

提前致谢。

2 个答案:

答案 0 :(得分:3)

您需要遍历READ语句。单个READ只会到达记录的末尾,在本例中为行。当你输出end = 200参数时,你会知道你的线路用完了,所以它会跳到第200行(你似乎没有这里)。

所以,你需要确保:

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

B)循环READ语句

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

例如,假设声明相同且数组分配得足够大,而且我是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,因为这是现代的并且不推荐使用行号。

答案 1 :(得分:3)

步骤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