【问题标题】:Fortran: formatted readFortran:格式化读取
【发布时间】:2013-02-14 12:20:27
【问题描述】:

我有一个看起来像这样的文件:

startSpecifier

(  251)-0.0110365 (  168)-0.0110365 ( 1267) 0.0108601 (  980) 0.0108601 (

(  251)-0.0110365 (

endSpecifier

我不知道该格式在 infile 中每行重复的频率。

我需要得到如下所示的数组(对于上面的示例):

a=[251, 268, 1267, 980, 251]
b=-0.0110365, -0.0110365, 0.0108601,...]

对于如何解决这个问题有什么建议吗?

【问题讨论】:

    标签: format fortran


    【解决方案1】:

    在我看来,你基本上有两种选择:

    • 您在 Fortran 中编写了一个链表,逐行读取文件,解析这些行并将提取的元素附加到链表中。读取完成后,将链表转换为数组。在DFTB+ 中读取未知长度的用户数据时,我们正在这样做,但不幸的是,这需要大量的编程。

    • 或者,您可以使用脚本语言从输入文件中提取数据并以更适合 Fortran 的格式存储。下面是一个 Python 示例,但您可以使用您选择的任何其他脚本语言:

      from __future__ import print_function
      import sys
      import re
      
      PAT1 = re.compile(r"\(\s*(?P<int>\d+)\)")
      PAT2 = re.compile(r"\)\s*(?P<float>-?\d+\.\d+)\s*\(")
      
      txt = sys.stdin.read()
      ints = PAT1.findall(txt)
      floats = PAT2.findall(txt)
      
      print(len(ints))
      print(" ".join(ints))
      print(" ".join(floats))
      

      将脚本存储为 convert.py 并像这样运行它:

      python convert.py < mydata.dat > newdata.dat
      

      我假设您的数据存储在mydata.dat 中。新文件newdata.dat
      然后看起来像:

      5
      251 168 1267 980 251
      -0.0110365 -0.0110365 0.0108601 0.0108601 -0.0110365
      

      通过读取第一行中的整数,您可以轻松地使用 Fortran 进行解析, 分配你的整数 并将数组浮动到其中给定的大小,并在两个数组中读取两个读取 声明。

    【讨论】:

      【解决方案2】:

      我会用

      do line = 1,nlines  !or just do and exit on end of file, it's up to you
          lower = (line-1)*items_per_line + 1
          upper = line*items_per_line
          read (unit,fmt='(999(tr1,i5,tr1,f11))') (a(i),b(i),i=lower,upper)
      end do
      

      添加任何其他read(unit,*) 以跳过适当的行。

      如果字段宽度确实是固定的,就像从您的示例中看到的那样。

      【讨论】:

      • 很遗憾我不知道我期望多少个字段,所以我不知道“上”。文件中的换行符有问题吗?
      • 对于换行符,您只需执行另一个相同的读取语句。 lower 是最后读取的数组索引 + 1(开头为 1),upper 是最后读取的索引 + 行中的项目数。无论如何,您都应该知道要读取的项目数,因为您的数组必须事先分配。
      • 那你先看吧,你不是程序员吗?你只需要知道为了知道你想从哪一行读到什么。另一种选择是通过删除括号来更改文件并使用list directed format read(unit,*)
      猜你喜欢
      • 2014-06-12
      • 1970-01-01
      • 2012-09-03
      • 1970-01-01
      • 1970-01-01
      • 2012-10-27
      • 2013-06-01
      • 2013-03-14
      • 1970-01-01
      相关资源
      最近更新 更多