简体   繁体   English

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

[英]Open and read data in one row in fortran 90

I did some dummy code to learn to open and read file. 我做了一些伪代码来学习如何打开和读取文件。 Let's say I have the following test.dat which reads 假设我有以下test.dat,内容为

1
2
3
4
5
6
7
8
9
10

I wrote the following code to open and read the data file 我写了下面的代码来打开和读取数据文件

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

The output is shown below, as expected 输出如下所示,如预期

 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.

However, if the data is stored in a single row as follows 但是,如果数据按如下方式存储在单行中

1 2 3 4 5 6 7 8 9 10

then the above code does not work as desired. 则以上代码将无法正常运行。 It only reads the first element in the row and then prompt an error 它仅读取行中的第一个元素,然后提示错误

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

So, my question is that I have a data file which contains 2879 (1 x 2879) numbers stored in a single row. 因此,我的问题是我有一个数据文件,其中包含2879(1 x 2879)个数字,存储在一行中。 How am I going to open and read all those numbers in the data file? 我将如何打开并读取数据文件中的所有这些数字?

Each Fortran read statement, by default, reads a list of values and then advances to the beginning of the next line. 默认情况下,每个Fortran read语句都会读取值列表,然后前进到下一行的开头。 Think of read as moving a cursor through the input file as it works. read视为在工作时在输入文件中移动光标。 So your statement 所以你的陈述

read(100,*) test

does what you expect when the numbers in the input file are on separate lines. 当输入文件中的数字位于单独的行上时,您会执行什么操作。 When they are all on the same line in the file the first read statement reads one value (ie test ) then advances to the beginning of the next line to read the next value but there isn't a next line and you get the runtime error you have shown us. 当它们都在文件的同一行上时,第一个read语句读取一个值(即test ),然后前进到下一行的开头以读取下一个值,但是没有下一行,则您会遇到运行时错误你给我们看了。

There are 2 straightforward solutions. 有2个简单的解决方案。

One, you could read multiple values from a line in one statement, for example, you might declare 一种,您可以在一条语句中从一行中读取多个值,例如,您可以声明

real, dimension(10) :: test

then 然后

read(100,*) test

should get all the values into the array in one go. 应该一次性将所有值放入数组。

Second, you could use non-advancing input, which tells the processor to not skip to the beginning of the next line after each read statement. 其次,可以使用non-advancing输入,它告诉处理器不要在每个read语句之后跳到下一行的开头。 Something like the following (check the edit descriptor for your circumstances) 类似于以下内容(请根据情况检查编辑描述符)

read(100,'(f8.2)',advance='no') test

If you choose this latter approach, don't forget that after you have read all the values from a line you do want to skip to the beginning of the next line so you may need to execute a statement such as 如果您选择后一种方法,请不要忘记从一行中读取所有值之后,您确实希望跳到下一行的开头,因此您可能需要执行如下语句:

read(100,*)

which doesn't read any values but does advance to the next line. 它不会读取任何值,但会前进到下一行。

As already pointed out before, you can read your data in a row by adding 如前所述,您可以通过添加来连续读取数据

advance='no'

and a proper format string (depending on your data; for example 'i2' is working for a data sheet like [1 2 3 4 5 6] ) to your read command. 和正确的格式字符串(取决于您的数据;例如,“ i2”适用于诸如[1 2 3 4 5 6]的数据表)用于您的读取命令。 Another useful trick is to additionally take care for the I/O status by writing it's value on a paramter (ie io) and exiting the do loop without the runtime error, even if you don't know the lenght of your data sheet. 另一个有用的技巧是通过在参数(即io)上写入I / O的值并退出do循环而不会出现运行时错误,从而照顾I / O状态,即使您不知道数据表的长度也是如此。 A complete program could for example look like: 例如,完整的程序可能如下所示:

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

Have fun! 玩得开心!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM