1

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

2
  • 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. Commented May 1, 2020 at 0:41
  • @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. Commented May 1, 2020 at 1:42

1 Answer 1

2

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 
Sign up to request clarification or add additional context in comments.

4 Comments

many many thanks for having put down that piece of code for me! I tried to compile and execute and this is what I got: "forrtl: severe (24): end-of-file during read, unit -129, file C:\Users\Michele Esposito\Lavoro\Bispectrum\Simulations\1000_500\2\windturb.dat"
Also, setting open(unit=100, file=inputfile, action='read', status='old', form='formatted',& iostat=iost, iomsg=iom), i get this error: error #6347: A * specifier is invalid at this point in the control list.
I don't really have time to debug your program. I suggest that you first try to run my code as I've written it (you will have to change the inputfile parameter, of course), that should work. Then, when you modify the code to your needs, go in small steps to see what changes and when it crashes.
Maybe I understood whare's the problem. It is in the blanks at the beginning of the second lines, which lead the program to interpret them as end-of-file. Because I tried to build a similar file with only the nodes records, and it worked. Then, formatting the SAME file, but in such a way that records were not left-justified, I got the same error. Then, HOW TO AVOID THIS ERROR (end-of-file) WHEN A LINE STARTS WITH BLANKS? Many Thanks.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.