I did some dummy code to learn to open and read file. Let's say I have the following test.dat which reads
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. 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. Think ofread
as moving a cursor through the input file as it works. So your statementdoes 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 (i.e.
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.There are 2 straightforward solutions.
One, you could read multiple values from a line in one statement, for example, you might declare
then
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 eachread
statement. Something like the following (check the edit descriptor for your circumstances)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
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
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. Another useful trick is to additionally take care for the I/O status by writing it's value on a paramter (i.e. io) and exiting the do loop without the runtime error, even if you don't know the lenght of your data sheet. A complete program could for example look like:
Have fun!