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

前端 未结 2 1057
北恋
北恋 2020-12-11 12:04

There is a file that has,say, 1000 frames. Each frame contains different number of lines.Each line has two columns of integers.But,I do not know how many number of lines eac

相关标签:
2条回答
  • 2020-12-11 12:20

    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
    

    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.

    0 讨论(0)
  • 2020-12-11 12:25

    One of the weaknesses of even modern versions of Fortran (IMO) is the lack of expanding arrays like std::vector in C++ or GArray in GLib/C. Yes, you could write such a thing yourself, but the lack of generics/templates means that you'd have to specialise for every type and kind, or mess about with class(*) and allocatable scalars... urgh.

    But I digress.

    There are two options I can see. The first is to do two passes through the file, first counting the number of lines between each space, and allocating your frame arrays as you go, and the second pass to actually fill the arrays with data.

    The second, possibly more "Fortran-y" way to do it is to have a temporary work array which is as large as you ever expect a single frame to be. Fill this with data, then when you reach the end of a frame, allocate an array of the right size and copy your just-read data into it.

    Neither solution is particularly great though unfortunately.

    0 讨论(0)
提交回复
热议问题