如何使用Fortran从某一行读取并在同一文件的末尾写入?

时间:2019-03-27 15:31:33

标签: fortran

我有一个看起来像这样的文件:

 -7307.5702506795660       -13000.895251555605       -11777.655135862333       0.52503289678626652       0.51683849096298218        31.160950279498426       -7307.5698242187500       -13000.900390625000       -11777.658203125000     
  -7307.5712457548034       -13000.883260393683       -11777.647978916109       0.52714817702425010       0.84740489721298218        20.800333023071289       -7307.5698242187500       -13000.900390625000       -11777.658203125000

我用这样的代码阅读它:

   open(1,file='my_file.txt',status='old')
   do
    read(1,*,end=10) xe,ye,ze,the,phe,enel,x0,y0,z0
    ...some mathematical calculations
   end do
10 close(1)

我现在需要做的是在相同文件的末尾添加计算结果,并在我这一行之后继续读取文件正在使用进行计算。

如何在Fortran中做到这一点?

1 个答案:

答案 0 :(得分:1)

通过在读取过程中跟踪您所在的行,可以轻松地做到这一点。但是,您需要确保有紧急出口,因为当您提出问题时,循环将不会结束,直到您将磁盘填满为止。

我也怀疑是否需要这样做。我将使用可分配的数组,将其设置为比您认为的要大的值,然后使用例程检查计数并调整某些块的大小。

无论如何,这是一个功能齐全的示例:

program test
  implicit none
  integer :: iunit, max
  integer :: iline
  real :: xe,ye,ze,the,phe,enel,x0,y0,z0

  iunit = 1
  max = 20

  open(iunit,file='my_file.txt',status='old')

  iline = 0
  do
     iline = iline + 1
     read(iunit,*,end=10) xe, ye, ze, the, phe, enel, x0, y0, z0

     ! call calculation(?)
     xe = xe / 1000. ! just to see a difference in the file

     call append(iunit, iline, xe, ye, ze, the, phe, enel, x0, y0, z0)

     ! bettter have this emergency exit, because file will never hit end using append
     if (iline > max) exit
  end do
10 close(iunit)

contains
  subroutine append(iunit, iline, xe, ye, ze, the, phe, enel, x0, y0, z0)
    implicit none
    integer, intent(in) :: iunit, iline
    real, intent(in) :: xe, ye, ze, the, phe, enel, x0, y0, z0

    integer :: i

    ! skip to end
    do
       read(iunit,*,end=20)
    end do
20 continue
    backspace(iunit) ! back off the EOF

    ! append to file
    write(iunit,*) xe, ye, ze, the, phe, enel, x0, y0, z0

    ! rewind file and skip to iline
    rewind(iunit)
    i = 0
    do
       i = i + 1
       read(iunit,*)
       if (i == iline) exit
    end do

  end subroutine append

end program test