在 Fortran 中解析字符串

问题描述 投票:0回答:3

我正在读取 Fortran 中的一个文件,该文件每行都有不确定数量的浮点值(目前,一行上大约有 17 个值)。我想将每行的第 n 个值读取到给定的浮点变量。我该怎么做呢?

在 C 中,我编写的方式是将整行读入字符串,然后执行如下操作:

for(int il = 0; il < l; il++)
{
    for(int im = -il; im <= il; im++)
        pch = strtok(NULL, "\t ");
}
for(int im = -l; im <= m; im++)
    pch = strtok(NULL, "\t ");
dval = atof(pch);

在这里,我不断地读取一个值并将其丢弃(从而缩短字符串),直到我准备好接受我正在尝试读取的值。

有什么办法可以在 Fortran 中做到这一点吗?在 Fortran 中是否有更好的方法来做到这一点?我的 Fortran 代码的问题似乎是

read(tline, '(f10.15)') tline1
不会缩短 tline (tline 是我的字符串,包含整行,tline1 是我试图将其解析成的内容),因此我无法使用与我在我的代码中相同的方法C 例程。

有什么帮助吗?

string parsing file-io fortran90
3个回答
2
投票

问题是 Fortran 是基于记录的 I/O 系统,而 C 是基于流的。

如果您可以访问 Fortran 2003 兼容编译器(现代版本的 gfortran 应该可以工作),您可以使用

stream
ACCESS
说明符来执行您想要的操作。

可以在此处找到示例。

当然,如果您真的愿意,您可以直接从 Fortran 使用 C 函数。两种语言的接口通常很简单,通常只需要一个带有小写名称和附加下划线的包装器(当然取决于编译器和平台)。来回传递数组或字符串通常并不是那么简单;但对于这个例子来说,这是不需要的。

一旦数据位于字符数组中,您就可以将其读入另一个变量,就像使用

ADVANCE=no
签名一样,即。

do i = 1, numberIWant
   read(tline, '(F10.15)', ADVANCE="no") tline1
end do

其中

tline
应在循环末尾包含您的号码。

由于基于记录的 I/O,

READ
语句通常会抛出记录末尾之后的内容。但
ADVANCE=no
告诉它不要这样做。


0
投票

如果您确切知道所需值从哪个位置开始,则可以使用

T
编辑描述符从该位置开始下一次读取。
例如,假设每个字段的宽度为 10 个字符,并且您想要读取第五个值。读取语句将如下所示。

read(file_unit, '(t41, f10.5)') value1

P.s.:您可以在运行时动态创建格式字符串,并在

t
之后使用正确的数字,通过使用字符变量作为格式,并使用内部文件写入来放入该数字。
假设您想要从位置
n
开始的值。然后它看起来像这样(我在单引号和双引号之间交替,以尝试使每个字符串的开始和停止位置更清楚):

write(my_format, '(a, i0, a)') "(t", n, ', f10.5)'
read(file_unit, my_format) value1

0
投票

或者,可以通过

WRITE
语句直接生成字符串作为输出,以去除任何不受欢迎的字符:

character(len=12), dimension(  12) :: file_name        ! filename
character(len=24), dimension(  12) :: files            ! directory path + filename
character(len= 8), dimension(  14) :: short            ! stores filename without path & file extension

...

do i=1,m
   files(i)= './debug/emi/'//file_name(i)
   write(short(i),"(a8)")    file_name(i)
end do
call show(io_unit, files, short)
!.. Generates the output
    file #: 1  ./debug/emi/cicle_a2.dat  cicle_a2
    file #: 2  ./debug/emi/cicle_a5.dat  cicle_a5
© www.soinside.com 2019 - 2024. All rights reserved.