Using do loop in a Fortran 90 program to read different number of lines for n frames?

The easiest way is like this (reverse the order of indexes for row and column if necessary and add declarations for all variables I skipped to keep it short). It first reads the file and determines the number of lines. Then it rewinds the file to start from the beginning and reads the known number of lines.

  integer,allocatable :: a(:,:)
  integer :: pair(2)
  integer :: unit

  unit = 11
  
  open(unit,file="test.txt")
  n = 0
  do
    read(unit,*,iostat=io) pair
    if (io/=0) exit
    n = n + 1
  end do
  
  rewind(unit)

  allocate(a(n,2))
  
  do i=1,n
    read(unit,*) a(i,:)
  end do
  
  close(unit)
  
  print *, a
  
end

The check if (io/=0) exit is generic and will trigger on any error or end of record/file condition encountered.

Fortran 2003 contains constants specific constants in the iso_fortran_env module that contain specific values the iostat= can have.

IOSTAT_END:
    The value assigned to the variable passed to the IOSTAT= specifier of an input/output statement if an end-of-file condition occurred.
IOSTAT_EOR:
    The value assigned to the variable passed to the IOSTAT= specifier of an input/output statement if an end-of-record condition occurred. 

So if you only want to check for the end of file condition, use

if (io/=iostat_end) exit

end use the iso_fortran_env module before.


One pass solution also can be done, using temporary array you can grow the array easily (the C++ vector does the same behind the scenes). You could even implement your own grow able class, but it is out of scope of this question.


If you have a long fixed-size array with your data and not an allocatable one, you can skip the first pass and just read the file with the iostat= specifier and finish reading when it is nonzero or equal to iostat_end.

Leave a Comment