读取文件并根据另一个文件更改编号

发布于 2025-01-09 04:08:05 字数 1301 浏览 1 评论 0原文

我知道如何更改一个文件中文本中的数字,但我需要使用这样的表格(假设 file=word):

 1 # K
 2 # L
 3 # M 

并在另一个文件 text.dat 中:

 1   1
 1   2
 1   3

在第二列中更改文本 KL< 中的数字 123 /code>, M 使用 Fortran 程序。我知道我可以使用数组,或者我可以像带索引的行一样读取它。有谁知道如何从不同文件中获取文本?我有问题如何将一个文件中不断变化的数字合并到使用两个文件的文本中。

我的起始代码:

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

我想要的结果应该如下所示:

1 K
1 L
1 M

我需要从第二个文件将三个数字更改为 K、L、M。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

美人骨 2025-01-16 04:08:05

在我们做任何其他事情之前,让我们摆脱那个goto什么都没有 可以来。这些行

        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

等效于

        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

,但看起来您正在尝试进行错误处理,这可能应该是 接下来

        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)

要注意的是,在相同的代码中多次读取同一个文件通常不是一个好主意。相反,让我们将用于读取 word 的代码(我相信您在代码中称之为 t2.dat?)从读取 text.dat< 的循环中取出/code>,并将每个 atom 存储在一个数组中,按照 Ian Bush 的评论:

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

请注意,我已将最后一个 atom 替换为 atoms(3)< /code> 当你在循环之外编写它时,所以它将取最终值。这可能不是您想要的。

现在我们可以查看读取 text.dat 和写入 res 的循环。首先,您仅从 text.dat 的每一行读取一个整数。您可能想从每一行读取两个整数。此外,对于此类任务,通常最好使用列表定向读取而不是格式化读取,因为它们对文件格式更灵活。所以你的行将

read(unit=line,fmt='(i2)') p

变成

read(unit=line, *) a, p

现在你可以寻找与p匹配的atom。您可以简单地以 atoms(p) 的形式访问它,而不是滚动浏览文件并查找匹配项。所以你的代码将变成

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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文