1

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

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,...]

关于如何解决问题的任何建议?

4

2 回答 2

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 进行解析,将整数和浮点数组分配给其中给定的大小,并使用两个读取语句读取两个数组。

于 2013-02-28T19:23:17.967 回答
0

我会用

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,*)以跳过适当的行。

如果字段宽度确实是固定的,从您的示例中可以看出。

于 2013-02-28T11:14:11.400 回答