Before we do anything else, let's get rid of that goto
. Nothing good can come of it. The lines
read(unit=12,fmt='(a)') lmpline
k=index(lmpline,'#');if(k==0) goto 90
atom=lmpline(k:k+6)
k=len_trim(atom)
90 write(11,'(i2,a)') k, atom
are equivalent to
read(unit=12,fmt='(a)') lmpline
k=index(lmpline,'#')
if (k/=0) then
atom=lmpline(k:k+6)
k=len_trim(atom)
endif
write(11,'(i2,a)') k, atom
but it looks like you're trying to to error handling, which should probably instead be
read(unit=12,fmt='(a)') lmpline
k=index(lmpline,'#')
if (k==0) then
write(11,'(i2,a)') k, atom
stop
endif
atom=lmpline(k:k+6)
k=len_trim(atom)
The next thing to note is that it's not generally a good idea to read through the same file lots of times in the same code. Instead, let's pull your code for reading word
(which I believe you call t2.dat
in your code?) out of the loop for reading text.dat
, and store each atom
in an array, as per Ian Bush's comments:
program prevod
implicit none
integer :: i, k, maxgrps, a, p
character(LEN=40):: afile, line, lmpline
parameter (maxgrps=10)
character*10 :: atoms(3), blank, atpname(maxgrps)
logical :: elements, first
afile="t2.dat"
open(12,file=afile,status='old')
do a=1,3
read(unit=12,fmt='(a)') lmpline
k=index(lmpline,'#')
if (k==0) then
write(*, *) k, atom
stop
endif
atoms(a)=lmpline(k:k+6)
enddo
close(12)
open(20, file = "text.dat",status='old')
open(11,file="res",status='unknown')
do i=1,3
read(20,fmt='(a)') line
read(unit=line,fmt='(i2)') p
if(index(line,'element')==0) then
do a=1,3
k=len_trim(atoms(a))
write(11,'(i2,a)') k, atoms(a)
enddo
write(11,'(i2,a)') atoms(3)
endif
enddo
end program prevod
Note that I've replaced the last atom
with atoms(3)
as you're writing it outside the loop, so it will take the final value. This is probably not what you want.
Now we can look at your loop for reading text.dat
and writing res
. First off, you're only reading one integer
from each line of text.dat
. You probably want to read both integers from each line. Also, it's generally better to use list-directed reads rather than formatted reads for this kind of task, as they are more flexible to file format. So your line
read(unit=line,fmt='(i2)') p
would become
read(unit=line, *) a, p
Now you can look for the atom
which matches p
. Rather than scrolling through a file and finding the match, you can simply access this as atoms(p)
. And so your code would become
program prevod
implicit none
integer :: i, k, maxgrps, a, p
character(LEN=40):: afile, line, lmpline
parameter (maxgrps=10)
character*10 :: atoms(3), blank, atpname(maxgrps)
logical :: elements, first
afile="t2.dat"
open(12,file=afile,status='old')
do a=1,3
read(unit=12,fmt='(a)') lmpline
k=index(lmpline,'#')
if (k==0) then
write(*, *) k, atom
stop
endif
atoms(a)=lmpline(k:k+6)
enddo
close(12)
open(20, file = "text.dat",status='old')
open(11,file="res",status='unknown')
do i=1,3
read(20,fmt='(a)') line
read(unit=line, *) a, p
write(11,'(i2,a)') a, atoms(p)
enddo
end program prevod