mattiav27
mattiav27

Reputation: 685

How to read from a certain line and write at the end of the same file using Fortran?

I have a file which looks like this:

 -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

I read it with a code like this:

   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)

What I need to do now is add the result of my computation at the end of the same file and continue to read my file after the line I was calculating with.

How can I do this in Fortran?

Upvotes: 0

Views: 303

Answers (1)

SKempf
SKempf

Reputation: 73

You can easily do this by keeping track of the line you are on during the read. However, you need to make sure you have an emergency exit, because as the question is asked, the loop will not end until you fill your disk up.

I would also doubt this is needed. I would use an allocatable array, set it larger than you think you need, and then have a routine to check the count and adjust the size in certain chunks.

In any case, here is a fully functional example:

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

Upvotes: 1

Related Questions