我想从输入文件中读取坐标。示例输入文件类似于:
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,:)
?那会有用吗?
atnum, coord and element
,程序编译正常,但在我尝试运行它时会返回分段错误。如何在不事先分配动态数组的情况下让它读入动态数组?
听起来类似于这个问题:Variable size arrays in Fortran without Allocate()
提前致谢。
答案 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