如何提取字母数字链中间的浮点数?
How do I extract a floating number in the middle of an alphanumeric chain?
我正在用 Fortran 95 编写代码。
我必须从 ascii 文件中的这一行提取两个浮点值:
circle(4097.0438,4111.337)
READ语句当然是
read(unit=11, fmt="(tr7,f9.4,tr1,f8.3)") x, y
问题是我必须对数百个 ascii 文件执行此操作,但位数有所不同。例如:
circle(201.043,7250.1234) # which would require fmt="(tr7,f7.3,tr1,f9.4)"
circle(0.004038,9999.12) # which would require fmt="(tr7,f8.6,tr1,f7.2)"
circle(0.004038,22.1234) # etc
因此我不能使用单一格式。我不知道如何使用自由格式读取那些 x、y 坐标,因为无论如何我都必须跳过前 7 个空格。
将数据读入字符串缓冲区并删除不需要的部分可能有效。
program main
character(100) :: buf
real :: x, y
read( *, "(a)" ) buf
buf = buf( 8 : len(trim(buf))-1 ) !! remove "circle(" and ")"
read( buf, * ) x, y !! read two reals (commas/spaces are regarded as separators)
print *, x, y
end
另一种方法是使用 index() 查找“(”和“)[另请参阅 ref]。在这种情况下,数据可能包含“(”之前或“)”之后的任何字符串.更复杂的情况下可以用类似的方法提取必要的部分
integer :: n1, n2
n1 = index( buf, "(" )
n2 = index( buf, ")" )
read( buf( n1+1 : n2-1 ), * ) x, y
为了补充 我会添加一个 "cute" 东西。这采用了建议的方法,即使用来自内部文件的列表定向输入。
program main
character(100) :: buf
complex :: temp
real :: x, y
read( *, "(a)" ) buf
read(buf(7:), *, decimal='point') temp ! read a complex
x = temp%RE ! assign x as real part of that
y = temp%IM ! assign y as imaginary part
print *, x, y
end
[而不是 temp%RE
、temp%IM
,可能 REAL(temp)
、AIMAG(temp)
。]
这是可行的,因为我们知道对于具有列表定向输入的复数(Fortran 2008、10.10.3)
the input form consists of a left parenthesis followed by an ordered pair of numeric input fields separated by a comma (if the decimal edit mode is POINT) or semicolon (if the decimal edit mode is COMMA), and followed by a right parenthesis.
我在上面的代码中明确了 decimal='point'
。我也没有从缓冲区字符变量本身中删除前缀。
是的,除了不用担心删除括号外,这提供的很少。
我正在用 Fortran 95 编写代码。
我必须从 ascii 文件中的这一行提取两个浮点值:
circle(4097.0438,4111.337)
READ语句当然是
read(unit=11, fmt="(tr7,f9.4,tr1,f8.3)") x, y
问题是我必须对数百个 ascii 文件执行此操作,但位数有所不同。例如:
circle(201.043,7250.1234) # which would require fmt="(tr7,f7.3,tr1,f9.4)"
circle(0.004038,9999.12) # which would require fmt="(tr7,f8.6,tr1,f7.2)"
circle(0.004038,22.1234) # etc
因此我不能使用单一格式。我不知道如何使用自由格式读取那些 x、y 坐标,因为无论如何我都必须跳过前 7 个空格。
将数据读入字符串缓冲区并删除不需要的部分可能有效。
program main
character(100) :: buf
real :: x, y
read( *, "(a)" ) buf
buf = buf( 8 : len(trim(buf))-1 ) !! remove "circle(" and ")"
read( buf, * ) x, y !! read two reals (commas/spaces are regarded as separators)
print *, x, y
end
另一种方法是使用 index() 查找“(”和“)[另请参阅 ref]。在这种情况下,数据可能包含“(”之前或“)”之后的任何字符串.更复杂的情况下可以用类似的方法提取必要的部分
integer :: n1, n2
n1 = index( buf, "(" )
n2 = index( buf, ")" )
read( buf( n1+1 : n2-1 ), * ) x, y
为了补充
program main
character(100) :: buf
complex :: temp
real :: x, y
read( *, "(a)" ) buf
read(buf(7:), *, decimal='point') temp ! read a complex
x = temp%RE ! assign x as real part of that
y = temp%IM ! assign y as imaginary part
print *, x, y
end
[而不是 temp%RE
、temp%IM
,可能 REAL(temp)
、AIMAG(temp)
。]
这是可行的,因为我们知道对于具有列表定向输入的复数(Fortran 2008、10.10.3)
the input form consists of a left parenthesis followed by an ordered pair of numeric input fields separated by a comma (if the decimal edit mode is POINT) or semicolon (if the decimal edit mode is COMMA), and followed by a right parenthesis.
我在上面的代码中明确了 decimal='point'
。我也没有从缓冲区字符变量本身中删除前缀。
是的,除了不用担心删除括号外,这提供的很少。