Reputation: 21
I am trying to read multiple variables from a txt file I created using Fortran. The number of lines of the file was random as well as the numbers written on each line.
The file looks something like this:
1061 2.5 5.0 7.5 3.5
1062 9.0 2.5 10.0 7.5
Then I open the file on a separate Fortran program and try to read from it.
My code looked something like this, a
is an integer
, while b
, c
, d
, e
and f
are all real values:
open(10,file='data.txt',form='unformatted')
do
read(10,*,iostat=st) a,b,c,d,e
if(st==-1) exit
f=a+b+c+d+e
end do
When I try to run the program, than a runtime error appears telling me that I am referring on undefined variables and when I try to run the debugger, the variables a
, b
, c
, d
and e
stay undefined even after the read command.
Upvotes: 2
Views: 1775
Reputation: 1608
Just summarizing the comments and the existing answer, you should remove the
'unformatted'
keyword in the open statement, as fortran
reads text files
as your data.txt
as formatted one by default.
Assuming that your text file might look like this:
1061 2.5 5.0 7.5 3.5
1062 9.0 2.5 10.0 7.5
1063 4.0 3.1 3.2 5
1064 2.1 1.9 ***** 7.8
1065 1.0 4.0 10.0 3.5
1066 4.4 1.9 2.5
1067 6.7 8.8 10.9 12.0
then you should handle the different formatting errors following this minimal example:
program FileIO
implicit none
character(256) :: line
character(80) :: msg
integer :: a,st
real :: b,c,d,e,f
open(10,file='data.txt')
do
write(*,'(A)') '------------------------------------------------------------'
read(10,'(A)',iostat=st) line ! Buffer input in line
write(*,'(A)') 'Reading of line '//trim(line)
if (st < 0) then ! End of file or end of record
exit
else
read(line,*,iostat=st,iomsg=msg) a,b,c,d,e
write(*,'(A)') 'IO-message is: '//trim(msg)
if (st == 0) then ! Read one line successfully
write(*,'(A)') 'Line successfully read: '//trim(line)
f=a+b+c+d+e ! Calculate result
else
write(*,'(A)') 'IO-error occured in line: '//trim(line)
f=0
endif
endif
end do
close(10)
end program FileIO
A negative result for iostat
indicates an end of file or end of record event. A positive result for iostat
indicates a run-time error message, see e.g. for Intel Fortran.
This should be handled by an if
condition.
I recommend you to buffer the file input in a character variable, e.g. line
.
It helps you to write the error generating line back to a log file or standard
output.
The minimal example generates this output:
------------------------------------------------------------
Reading of line 1061 2.5 5.0 7.5 3.5
IO-message is:
Line successfully read: 1061 2.5 5.0 7.5 3.5
------------------------------------------------------------
Reading of line 1062 9.0 2.5 10.0 7.5
IO-message is:
Line successfully read: 1062 9.0 2.5 10.0 7.5
------------------------------------------------------------
Reading of line 1063 4.0 3.1 3.2 5
IO-message is:
Line successfully read: 1063 4.0 3.1 3.2 5
------------------------------------------------------------
Reading of line 1064 2.1 1.9 ***** 7.8
IO-message is: list-directed I/O syntax error, unit -5, file Internal List-Directed Read
IO-error occured in line: 1064 2.1 1.9 ***** 7.8
------------------------------------------------------------
Reading of line 1065 1.0 4.0 10.0 3.5
IO-message is: list-directed I/O syntax error, unit -5, file Internal List-Directed Read
Line successfully read: 1065 1.0 4.0 10.0 3.5
------------------------------------------------------------
Reading of line 1066 4.4 1.9 2.5
IO-message is: end-of-file during read, unit -5, file Internal List-Directed Read
IO-error occured in line: 1066 4.4 1.9 2.5
------------------------------------------------------------
Reading of line 1067 6.7 8.8 10.9 12.0
IO-message is: end-of-file during read, unit -5, file Internal List-Directed Read
Line successfully read: 1067 6.7 8.8 10.9 12.0
------------------------------------------------------------
Reading of line 1067 6.7 8.8 10.9 12.0
The list-directed reading of line 1063 works fine, even if the number 5
is
given as integer to the real variable e
. The formatting error *****
of line
1064 is detected correctly as well as the missing number in line 1066.
Please have a look to the Intel Fortran help regarding list-directed reading, if you need more information.
Hope it helps.
Upvotes: 1
Reputation: 59
It seems to me that your file is a formatted file (in fact you use *
as format). However you define it as 'unformatted'
in the open
statement. Try to set
form='formatted'
in your open
statement or just omit the form=
clause, since the default is formatted.
Upvotes: 4