问题
I am doing a chemistry research project and presently have a 378 x 378 matrix of zeros and ones in a file called Connectivity-M.txt
. I am trying to write a simple program to read down each column of the matrix and look for entries with a value of one. Since the matrix is of the format A(i,j)
I want to program to write the i
,j
location for each value of one that it finds to a new file, Wires.txt
. Here is my code so far:
program connectivity_matrixread
IMPLICIT none
integer :: i , j
INTEGER, DIMENSION(378,378) :: A
open(unit = 1 , file = "Connectivity-M.txt")
open(unit = 2 , file = "Wires.txt")
! Read values
do i = 1 , 378
do j = 1 , 378
Read(1,*) A(i,j)
if (A(i,j) .eq. 1) then
write(2,*) i , j
endif
enddo
enddo
end program connectivity_matrixread
The program manages to read the first column where there is only a single entry with a value of 1. It writes the i
,j
position of this entry but otherwise I get an error that reads:
At line 25 of file conn-read.f90 (unit = 1, file = 'Connectivity-M.txt')
Fortran runtime error: End of file
After moving the open file statement I am still getting the same error. The line the error refers to contains the read statement.
回答1:
Depending on the layout of the contents of your input file and how you open it, you can probably read it in one line, like this:
read(1,*) A
and let Fortran take care of the details. If you've got your array stored in row-major order I expect that this quick and easy method will read it in the 'wrong' order, so you may want to transpose the array after reading it. Or you may want to read it row by row rather like this:
do ix = 1,nrows
read(1,*) A(ix,:)
end do
These approaches will only work if there are the right number of integers in each row of the file and the right number of rows.
While I'm writing, a couple of bits of unasked for advice:
- Don't get into the habit of using single-digit unit identifiers in your programs. It's unusual these days to find identifiers other than 0, 5 and 6 already in use when your program starts, but not completely impossible. If you have a (very) up-to-date compiler use the option
NEWUNIT=UNIT
in yourOPEN
statements, if not use a number with at least 2 digits. - It's the 21st Century, you can drop the archaic
.eq.
and use==
now; it looks like Fortran 95 and later have gained acceptance.
And to answer your question: Yes, the error statement refers to the source line that was executing when the error occurred. The most likely causes of an unexpected end-of-file are that either the file isn't where the program is looking for it (Fortran thinks of non-existent files as being almost the same as empty files) or the file contains less data than you tried to read from it. The cause of this latter error might be either that the file contains less data than you thought, or that your read statement(s) attempted to read more than you thought they did. I can't tell which is the case without seeing your input file. Whatever you do don't post your whole input file, but if you are still having problems post a snippet of it.
To check that a file exists before trying to open it use the inquire
statement.
I'm made suspicious that you haven't figured out entirely what is going on because you write The program manages to read the first column while your code, quite clearly, reads the values into the array row-by-row.
回答2:
It may require more adjustment after this, but the first step is to move the open statement up, above the loops, like this:
open(unit = 1 , file = "Connectivity-M.txt")
do i = 1 , 378
do j = 1 , 378
The reason is that the file should be opened only once, then you iterate through it.
Post your result and we'll see what's next.
来源:https://stackoverflow.com/questions/13034143/how-to-read-a-matrix-and-write-certain-values-to-a-new-file-in-fortran