1
votes

I have a file that writes like this

N
                1000
NNODES
                   3
TURB_INT
             0.20000
U_MEAN
                  30
TYPE_GP
                 dav
L
                 120
WIND_TURB
              NODE_1              NODE_2              NODE_3

             0.90139            -1.02858             0.03962
            -2.56887            -1.59726            -0.82062
            -0.58745             0.72129            -1.90712
            -4.46302            -2.49995            -5.45345
            -4.10550            -5.50565            -7.77285
            -6.18588            -6.34998            -5.95054

I am really struggling to understand how to read it.

Finally what I need the most is reading the NODES records into variable WT(i,:), hence I could use a DO loop.

Here is what I have:

! open inputfile, ID=100
    open(unit=100, file=inputfile, recl=fileln, status='old', iostat=iost)

    print *, iost
    print *, fileln

    if (iost .ne. 0) then 
        print *, 'Error opening file'
        print *, erromsg
    else
        print *, 'File opened correctly'
        print *, erromsg
    end if


    ! Trying to read what's written in file.
    read(unit=100, *) N
    print *, N

    read(unit=100, *) Nval
    print *, Nval

I was trying to see how reading is done line by line. I can read variable N, but right at second reading (line 2) I have "severe(24): END OF FILE during read".

Please could you advise me? Thanks

1
What is your fileln? Is that the file size? That would explain it reading the whole file in the first read (only storing what can fit into N) and then being at the end of the file for the second read. - chw21
@JavierGarcia are you sure about recl only working on unformatted output. My understanding is that you can also use it with formatted, just that all the records have to be the same length. Which in the example file they aren't. - chw21

1 Answers

2
votes

I think you should read up on the proper flags for your open statement. The keyword recl is used for direct access files. It means that every record has the same length, so if you need the 64th record, the program knows immediately where that record is.

If your file has a record length, I can't see it. As I said in my comment, I have the strong suspicion that fileln is the length of the file in bytes (you didn't say). So in your first read, the first record would be read, which is the entirety of the file, and then parsed into the variable N -- which can only take a single integer, everything else is then discarded.

And then it tries to read the next fileln bytes after the end of the file, which results in an 'end of file' error.

In your case, I would add the action="READ" and form="FORMATTED" keywords in the file open statement. And I always find it useful to not only look for the error code, but also the error message iomsg.

For what it's worth, here's my suggestion on how to read the file:

program readfile
    implicit none
    integer :: u  ! File handle
    integer :: ios
    character(len=100) :: iom, line
    integer :: N, NNodes, U_Mean, L
    real :: Turb_Int
    character(len=20) :: Type_GP
    real, allocatable :: node_values(:)
    character(len=10), allocatable :: node_names(:)
    character(len=*), parameter :: inputfile = 'data.txt'

    ! newunit, instead of unit, creates a new unique
    ! file unit number. You could also set u to 100
    ! and then use unit=u
    open(newunit=u, file=inputfile, action='READ', &
        status='OLD', form='FORMATTED', iostat=ios, &
        iomsg=iom)

    if (ios /= 0) then
        print *, "Error opening file:"
        print *, iom
        stop 1
    end if

    ! Read the header. I'm always reading 'line' when
    ! I expect there to be just the next keyword
    ! in the line. You might want to check for that
    read(u, *) line   ! Hopefully 'N'
    read(u, *) N
    read(u, *) line   ! Hopefully "NNODES"
    read(u, *) NNodes
    ! I assume that NNODES stands for the number
    ! of columns later in the file.
    ! So here I'm also allocating the arrays.
    allocate(node_values(NNodes))
    allocate(node_names(NNodes))
    read(u, *) line   ! Hopefully TURB_INT
    read(u, *) Turb_Int
    read(u, *) line   ! Hopefully U_MEN
    read(u, *) U_Mean
    read(u, *) line   ! Hopefully TYPE_GP
    read(u, *) Type_GP
    read(u, *) line   ! Hopefully L
    read(u, *) L
    read(u, *) line   ! Hopefully WIND_TURB
    read(u, *) node_names

    ! Just print out what we got from the header so far to see
    ! everyting's right
    write(*, '(A, I0)') "N = ", N
    write(*, '(A, I0)') "NNodes = ", NNodes
    write(*, '(A, F5.1)') "Turb_Int = ", Turb_Int
    write(*, '(A, I0)') "U_Mean = ", U_Mean
    write(*, '(A, A)') "Type_GP = ", trim(Type_GP)
    write(*, '(A, I0)') "L = ", L
    write(*, '(A, *(A))') node_names

    ! Now read the data itself. In this case I'm just reading it
    ! line by line, print it out, and forget it again
    ! until the end of the file.
    data_loop : do
        read(u, *, iostat=ios, iomsg=iom) node_values
        if (ios /= 0) exit data_loop
        print *, node_values
    end do data_loop
end program readfile