在Fortran 90程序中使用do循环来读取n帧的不同行数?

时间:2013-10-31 17:38:07

标签: fortran fortran90

有一个文件有1000帧。每个帧包含不同数量的行。每行有两列整数。但是,我不知道每帧包含多少行。每个帧由一个空行分隔。我想读取这些值并将它们存储在一个数组中。但是,我无法分配数组大小,因为我不知道每帧有多少行。所以,我有两个问题:

  • 如何使用“do”循环读取fortran90程序中的不同行数?我不能使用“count-controlled do”循环,因为我不知道每帧中的确切行数。
  • 如果我之前无法分配数字,如何将数字存储在数组中? 该文件看起来像这样:
1   2  
2   1

3   2

2   8   
4   5  
4   17  
2   10

依旧......

有什么建议吗?

2 个答案:

答案 0 :(得分:5)

最简单的方法就是这样(如果需要,可以反转行和列的索引顺序,并为我跳过的所有变量添加声明以保持简短)。它首先读取文件并确定行数。然后它将文件重新开始从头开始并读取已知的行数。

  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

也可以使用临时数组完成一次通过解决方案,您可以轻松地扩展数组(C ++向量在幕后也是如此)。你甚至可以实现自己的成长能力课程,但这超出了这个问题的范围。

答案 1 :(得分:0)

即使是现代版本的Fortran(IMO)的弱点之一是缺少扩展数组,如C ++中的std::vector或GLib / C中的GArray。是的,您可以自己编写这样的东西,但缺少泛型/模板意味着您必须专注于每种类型和类型,或者使用class(*)和可分配的标量混乱... urgh。

但我离题了。

我可以看到两种选择。第一种方法是在文件中进行两次传递,首先计算每个空格之间的行数,然后分配帧数组,第二次传递实际用数据填充数组。

第二种,可能更“Fortran-y”的方法是拥有一个临时的工作阵列,它与你想象的单帧一样大。用数据填充,然后当你到达帧的末尾时,分配一个正确大小的数组并将你刚刚读取的数据复制到其中。

不幸的是,这两种解决方案都不是特别好。