rickitywrecked
rickitywrecked

Reputation: 21

Fortran can't read from file

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

Answers (2)

CKE
CKE

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

JEA
JEA

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

Related Questions