本文介绍了在 Fortran 90 程序中使用 do 循环读取 n 帧的不同行数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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 each frame contains. Every frame is separated by one blank line.I want to read these values and store them in an array. But,I cannot allocate the array size as I do not know how many lines every frame has. So, I have two questions:

  • 如何使用do"循环读取 fortran90 程序中的不同行数?我无法使用计数控制执行"循环,因为我不知道每帧中的确切行数.
  • 如果我不能更早地分配数组的大小,如何将数字存储在数组中?该文件如下所示:
1   2
2   1

3   2

2   8
4   5
4   17
2   10

等等……

有什么建议吗?

推荐答案

最简单的方法是这样(必要时颠倒行和列的索引顺序,并为我跳过的所有变量添加声明以保持简短).它首先读取文件并确定行数.然后它倒带文件从头开始并读取已知行数.

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


检查 if (io/=0) exit 是通用的,将在遇到任何错误或记录/文件结束条件时触发.


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

Fortran 2003 包含常量 iso_fortran_env 模块中的特定常量,这些常量包含 iostat= 可以具有的特定值.

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

结束使用之前的iso_fortran_env模块.

也可以完成一次通过的解决方案,使用临时数组您可以轻松地增加数组(C++ 向量在后台执行相同的操作).你甚至可以实现自己的成长类,但这超出了这个问题的范围.

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.

如果您的数据有一个固定大小的长数组,而不是一个可分配的数组,您可以跳过第一遍,只需使用 iostat= 说明符读取文件,然后在读取完成时完成读取非零或等于 iostat_end.

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.

这篇关于在 Fortran 90 程序中使用 do 循环读取 n 帧的不同行数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-30 01:43