在fortran 90中打开并读取一行数据

时间:2013-10-17 08:11:14

标签: fortran fortran90

我做了一些虚拟代码来学习打开和读取文件。假设我有以下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)个数字。我如何打开并读取数据文件中的所有数字?

2 个答案:

答案 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

玩得开心!