最简单的方法是这样的(如有必要,颠倒行和列的索引顺序,并为我跳过的所有变量添加声明以保持简短)。它首先读取文件并确定行数。然后它倒带文件从头开始并读取已知行数。
integer,allocatable :: a(:,:)
integer :: pair(2)
integer :: unit
unit = 11
open(unit,file="test.txt")
n = 0
do
read(unit,*,iostat=io) pair
if (io/=0) exit
n = n + 1
end do
rewind(unit)
allocate(a(n,2))
do i=1,n
read(unit,*) a(i,:)
end do
close(unit)
print *, a
end
检查if (io/=0) exit
是通用的,将在遇到任何错误或记录/文件结束条件时触发。
Fortran 2003 包含常量iso_fortran_env
模块中的特定常量,这些常量包含可以具有的特定值iostat=
。
IOSTAT_END:
The value assigned to the variable passed to the IOSTAT= specifier of an input/output statement if an end-of-file condition occurred.
IOSTAT_EOR:
The value assigned to the variable passed to the IOSTAT= specifier of an input/output statement if an end-of-record condition occurred.
因此,如果您只想检查文件结束条件,请使用
if (io/=iostat_end) exit
结束之前use
的iso_fortran_env
模块。
也可以完成一次通过的解决方案,使用临时数组,您可以轻松地增长数组(C++ 向量在幕后做同样的事情)。你甚至可以实现自己的成长类,但这超出了这个问题的范围。
如果您的数据有一个固定大小的长数组而不是可分配的数组,您可以跳过第一遍,只使用说明iostat=
符读取文件,并在它非零或等于时完成读取iostat_end
。