Reputation: 15
I've currently created a code that can open a file from an in putted directory, then begin sorting that data into two different arrays, an integer and a character. The input file looks like this:
1817
Plot50.0.xyz
C 0.70900 0.00000 0.00000
C 0.00000 1.22802 0.00000
C 2.12700 0.00000 0.00000
C 2.83600 1.22802 0.00000
C 4.96300 0.00000 0.00000
C 4.25400 1.22802 0.00000
C 6.38100 0.00000 0.00000
C 7.09000 1.22802 0.00000
C 9.21700 0.00000 0.00000
C 8.50800
Now I'm not sure if maybe I haven't allocated everything correctly when opening the file (format etc) but here is the code [working]:
program test01
character(len=40) :: filename !Storing the file name
character(len=20) :: nam !Collecting the file name within the file
integer(8) :: N !Number of coordinates within the file
real(8), allocatable :: coa(:,:) !Array containing xyz coordinates
character(len=6), allocatable :: atom(:,:) !Array containing the atomic make up
integer(8) :: i,j,k !Do loop parameters
filename = ''
write (6,*) 'Enter file name'
read (5,*) filename
open (10, file=filename, status='OLD')
write (6,*) 'Sucessfully opened file:', filename
read(10,*) N
allocate (coa(N,4))
allocate (atom(N,1))
read (10,*) nam
print*, nam
i = 0
do while (i < N)
read(10,*) atom(i,1), coa(i,2:4)
i = i+1
end do
print*, atom(0,1), atom(1,1), atom(4,1), atom(1818,1) !checking
print*, coa(0,2), coa(1500,3) !checking
close (10)
end program test01
So my main question lies with, are there any better ways to create the arrays (needs to be two as I believe characters and real cannot be mixed, and the coa
array while be used for calculations later on) and specifically extract certain data from the file (more so to skip the row 2 of the file instead of inserting it into a character to remove it as it was causing all the issues when I was trying to create the arrays).
Upvotes: 1
Views: 2099
Reputation: 78354
You write are there any better ways to create the arrays. Let's start with a correct way, which this isn't ...
i = 0
do while (i < N)
read(10,*) atom(i,1), coa(i,2:4)
i = i+1
end do
That looks to be like a C loop (for (i=0; i<N; i++)
) written in Fortran and it makes the mistake of starting indexing into the arrays at row 0
. Since the code makes no effort to start the array indexes at 0
, and Fortran defaults to indexing from 1
, the first execution of the read
will read data into memory locations outside the extent of the arrays.
A correct and more Fortranic way would be
do i = 1, N
read(10,*) atom(i,1), coa(i,2:4)
end do
I see that elsewhere you've printed values from row 0
of the arrays. You got 'lucky' that those outside-the-bounds accesses don't go to addresses outside the program's address space and lead to segmentation faults.
The program is broken, it's just that it's only a little broken and hasn't caused you any pain yet.
Upvotes: 2