fortranfortran90overwrite

overwrite a file using fortran


I am using a Fortran 90 program that writes a file. The first line of this file is supposed to indicate the number of lines in the remaining file. The file is written by the program when a certain criterion is met and that can't be determined beforehand. Basically, I will know the total number of lines only after the run is over.

I want to do it in the following manner:

1) open the file and write the first line with some text say, "Hello"

2) Write rows in the file as desired and keep a counter for number of rows.

3) Once the run is over and just before closing the file, replace the first line string ("Hello") with the counter.

The problem is in step 3. I don't know how to replace the first line.

Another option that I can think of is to write to 2 files. First, write a file as above without the counter. Once the run is over, close the file and write another file and this time, I know the value of the counter.

I believe there is a way to proceed with the first approach. Can someone please help me with this?


Solution

  • Going back on a sequential access file is tricky, because lines can vary in length. And if you change the length of one line, you'd have to move all the stuff behind.

    What I recommend is to write your output to a scratch file while counting the number of lines. Then, once you're finished, rewind the scratch file, write the number of lines to your output file, and copy the contents of the scratch file to that output file.

    Here's what I did:

    program var_file
        implicit none
        character(len=*), parameter :: filename = 'delme.dat'
        integer :: n, io_stat
        character(len=300) :: line
    
        open(unit=200, status='SCRATCH', action="READWRITE")
    
        n = 0
    
        do
            read(*, '(A)') line
            if (len_trim(line) == 0) exit  ! Empty line -> finished
            n = n + 1
            write(200, '(A)') trim(line)
        end do
    
        rewind(200)
    
        open(unit=100, file=filename, status="unknown", action="write")
        write(100, '(I0)') n
    
        do
            read(200, '(A)', iostat=io_stat) line
            if (io_stat /= 0) exit
            write(100, '(A)') trim(line)
        end do
    
        close(200)
        close(100)
    
    end program var_file