9

I'm trying to read a file into memory in a Fortran program. The file has N rows with two values in each row. This is what I currently do (it compiles and runs, but gives me incorrect output):

program readfromfile
  implicit none

    integer :: N, i, lines_in_file
    real*8, allocatable :: cs(:,:)

    N = lines_in_file('datafile.txt') ! a function I wrote, which works correctly

    allocate(cs(N,2))

    open(15, 'datafile.txt', status='old')
    read(15,*) cs

    do i=1,N
        print *, cs(i,1), cs(i,2)
    enddo

end

What I hoped to get was the data loaded into the variable cs, with lines as first index and columns as second, but when the above code runs, it first gives prints a line with two "left column" values, then a line with two "right column" values, then a line with the next two "left column values" and so on.

Here's a more visual description of the situation:

In my data file:       Desired output:        Actual output:
A1   B1                A1   B1                A1   A2
A2   B2                A2   B2                B1   B2
A3   B3                A3   B3                A3   A4
A4   B4                A4   B4                B3   B4

I've tried switching the indices when allocating cs, but with the same results (or segfault, depending on wether I also switch indices at the print statement). I've also tried reading the values row-by-row, but because of the irregular format of the data file (comma-delimited, not column-aligned) I couldn't get this working at all.

How do I read the data into memory the best way to achieve the results I want?

1 Answer 1

12

I do not see any comma in your data file. It should not make any difference with the list-directed input anyway. Just try to read it like you write it.

do i=1,N
    read (*,*) cs(i,1), cs(i,2)
enddo

Otherwise if you read whole array in one command, it reads it in column-major order, i.e., cs(1,1), cs(2, 1), ....cs(N,1), cs(1, 2), cs(2,2), ... This is the order in which the array is stored in memory.

Sign up to request clarification or add additional context in comments.

3 Comments

I'm amazed at why I couldn't get this working before, but now it does. Thanks! Regarding the commas in my input file, they are there in the actual file, but in the example I just wanted to visualize the ordering of the elements.
And an upvote for the explanation of why it did what it did when it wasn't working. More rep to you, sir! =)
For future readers of this post: I wanted to generalize the read to a subroutine that just takes the file name and the number of rows and cols to read, and ended up with the following implicit do construct: read(f, *) ((cs(row,col),col=1,Ncols),row=1,Nrows). Note that the columns have to be in the inner loop, for reasons mentioned by @Vladimir F in the answer above.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.