0

I know how to change numbers in text in a one file, but I need to use table like this (lets say file=word):

 1 # K
 2 # L
 3 # M 

and in another file text.dat:

 1   1
 1   2
 1   3

in the second column change the numbers 1, 2, 3 in text K, L, M using Fortran program. I know I can use arrays or I can read it like a line with index. Does anyone has an idea how to do it taking the text from different file? I have problem how to combine changing numbers in one file to text employing two files.

My starting code:

program prevod
  implicit none
  
  integer :: i, k, maxgrps, a, p
  character(LEN=40):: afile, line, lmpline
  parameter (maxgrps=10)
  character*10 :: atom, blank, atpname(maxgrps)
  logical :: elements, first
  
  afile="t2.dat"
    
  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
      open(12,file=afile,status='old')
      do a=1,3
        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
      enddo
      write(11,'(i2,a)') atom
    endif
    close(12)
  enddo
end program prevod

The result I want should look like:

1 K
1 L
1 M

I need to from second file this change of three numbers to K, L, M.

No Pe
  • 31
  • 4
  • What kind of problems do you have? Did you try to write some code? What problems did you face? See [ask]. Also, please show the intended reult. – Vladimir F Героям слава Feb 22 '22 at 16:44
  • The result is K L M instead of 1 2 3 in the file. I have no idea how to use array or index in do loops to change number in these characters. – No Pe Feb 22 '22 at 18:12
  • 2
    In which file? You have two files. Please show the exact result you want. Regarding your starting code? What is wrong with it? Does it compile?Any error messages? Does it produce any results? What exact results? Show the output. – Vladimir F Героям слава Feb 22 '22 at 18:17
  • I am able to read both individual files. I don't have troubles with errors itself. I have no idea how to implement some array of elements from file obtaining 1 K etc. to change numbers 1 2 3 in these K L M characters. Let's say how to read an array of elements from file and get it for change in the second file. – No Pe Feb 22 '22 at 18:48
  • 1
    Implement a look up table in an array. The first element of the array hold 'K', i.e. `table( 1 ) = 'K'`, the second element holds 'L' and so on. Now once you have read a 1 from the first file can you see how you might translate this to K and then write it to the second file? – Ian Bush Feb 22 '22 at 19:21
  • So, I do not need to open afile like other files? I thought here must be always number when opening a file. – No Pe Feb 23 '22 at 07:06
  • Sorry, I apparently misread your code. Ignore my comments about `afile`. – veryreverie Feb 23 '22 at 08:45

1 Answers1

0

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
veryreverie
  • 2,871
  • 2
  • 13
  • 26
  • Thank you very much for the code and for very useful comments. Now I understand better. – No Pe Feb 23 '22 at 20:28