我做了一些虚拟代码来学习打开和读取文件。假设我有以下test.dat读取
1
2
3
4
5
6
7
8
9
10
我编写了以下代码来打开并读取数据文件
subroutine readdata
implicit none
integer :: j
double precision :: test
open(unit = 100, file = 'test.dat', status = 'old', action = 'read')
do j = 1, 10
read(100,*) test
print *, 'N1=', test
end do
end subroutine
输出如下所示
gfortran -g -I/usr/include -o main main.o subroutines.o -L/usr/lib64/liblapack -L/usr/lib64/libblas
test= 1.0000000000000000
test= 2.0000000000000000
test= 3.0000000000000000
test= 4.0000000000000000
test= 5.0000000000000000
test= 6.0000000000000000
test= 7.0000000000000000
test= 8.0000000000000000
test= 9.0000000000000000
test= 10.000000000000000
Main finished.
但是,如果数据存储在单行中,如下所示
1 2 3 4 5 6 7 8 9 10
然后上面的代码无法正常工作。它只读取行中的第一个元素,然后提示错误
sharwani@linux-h6qd:~/PHD_research/myCodes/data> ./runcase.sh
rm -f *.o *.mod *.MOD *.exe *.stackdump main
gfortran -g -I/usr/include -c main.f90
gfortran -g -I/usr/include -c subroutines.f90
gfortran -g -I/usr/include -o main main.o subroutines.o -L/usr/lib64/liblapack -L/usr/lib64/libblas
test= 1.0000000000000000
At line 9 of file subroutines.f90 (unit = 100, file = 'test.dat')
Fortran runtime error: End of file
所以,我的问题是我有一个数据文件,其中包含存储在一行中的2879(1 x 2879)个数字。我如何打开并读取数据文件中的所有数字?
答案 0 :(得分:11)
默认情况下,每个Fortran read
语句读取一个值列表,然后前进到下一行的开头。将read
视为在工作时将光标移动到输入文件中。所以你的陈述
read(100,*) test
当输入文件中的数字位于不同的行时,执行您的预期。当它们都在文件的同一行时,第一个read语句读取一个值(即test
)然后前进到下一行的开头读取下一个值,但是没有下一行而你得到你告诉我们的运行时错误。
有两种直接的解决方案。
一,您可以在一个语句中读取一行中的多个值,例如,您可以声明
real, dimension(10) :: test
然后
read(100,*) test
应该一次性将所有值都放入数组中。
其次,您可以使用non-advancing
输入,它告诉处理器在每个read
语句后不跳到下一行的开头。类似于以下内容(根据您的具体情况检查编辑描述符)
read(100,'(f8.2)',advance='no') test
如果选择后一种方法,请不要忘记,在读完一行中的所有值后,您确实要跳到下一行的开头,这样您可能需要执行一个语句,例如
read(100,*)
不会读取任何值但会前进到下一行。
答案 1 :(得分:0)
如前所述,您可以通过添加
连续读取数据advance='no'
和一个正确的格式字符串(取决于您的数据;例如'i2'用于数据表,如[1 2 3 4 5 6])到您的读命令。 另一个有用的技巧是通过在参数(即io)上写入它的值并在没有运行时错误的情况下退出do循环来另外注意I / O状态,即使您不知道数据表的长度。例如,完整的程序可能如下所示:
program read
integer::a,io
open(100, file='data')
do
read(100,'(i2)',advance='no',IOSTAT=io)a
if (io<0) exit
if (io>0) stop 'problem reading'
write(*,*)a
end do
end program
玩得开心!