我想用 Fortran 程序读取一个数据文件,其中每一行都是一个整数列表。
每行都有可变数量的整数,由给定字符(空格、逗号...)分隔。
样本输入:
1,7,3,2
2,8
12,44,13,11
我有一个分割线的解决方案,我发现它相当复杂:
module split
implicit none
contains
function string_to_integers(str, sep) result(a)
integer, allocatable :: a(:)
integer :: i, j, k, n, m, p, r
character(*) :: str
character :: sep, c
character(:), allocatable :: tmp
!First pass: find number of items (m), and maximum length of an item (r)
n = len_trim(str)
m = 1
j = 0
r = 0
do i = 1, n
if(str(i:i) == sep) then
m = m + 1
r = max(r, j)
j = 0
else
j = j + 1
end if
end do
r = max(r, j)
allocate(a(m))
allocate(character(r) :: tmp)
!Second pass: copy each item into temporary string (tmp),
!read an integer from tmp, and write this integer in the output array (a)
tmp(1:r) = " "
j = 0
k = 0
do i = 1, n
c = str(i:i)
if(c == sep) then
k = k + 1
read(tmp, *) p
a(k) = p
tmp(1:r) = " "
j = 0
else
j = j + 1
tmp(j:j) = c
end if
end do
k = k + 1
read(tmp, *) p
a(k) = p
deallocate(tmp)
end function
end module
我的问题:
在 Fortran 中有没有更简单的方法来做到这一点?我的意思是,读取一个值列表,其中要读取的值的数量是未知的。上面的代码看起来很别扭,在 Fortran 中文件 I/O 看起来并不容易。
此外,主程序必须读取长度未知且无限长的行。如果我假设它们都是相同的长度(见下文),我能够读取行,但我不知道如何读取无界行。我想它需要 Fortran 2003 的流功能,但我不知道怎么写。
这是当前的程序:
program read_data
use split
implicit none
integer :: q
integer, allocatable :: a(:)
character(80) :: line
open(unit=10, file="input.txt", action="read", status="old", form="formatted")
do
read(10, "(A80)", iostat=q) line
if(q /= 0) exit
if(line(1:1) /= "#") then
a = string_to_integers(line, ",")
print *, ubound(a), a
end if
end do
close(10)
end program
关于这个问题的评论:通常我会在 Python 中执行此操作,例如转换一行就像 . 一样简单a = [int(x) for x in line.split(",")]
,读取文件同样几乎是一项微不足道的任务。我会用 Fortran DLL 做“真正的”计算工作。但是,我想提高我在文件 I/O 方面的 Fortran 技能。