Fortran将字符串转换为数字
问题描述:
我想要一个将数字 字符串的内容转换为数值类型(int,real,double precision,real(real128))的子例程。Fortran将字符串转换为数字
但是,当尝试使用Class(*)
时出现错误。错误 如下所示:
gfortran -o build/lib/larsa.o -c -ffree-form -g -J./build/lib lib/larsa.f
lib/larsa.f:1933.35:
Read (s, frmt, iostat=ios) num
1
Error: Data transfer element at (1) cannot be polymorphic unless
it is processed by a defined input/output procedure
lib/larsa.f:1935.32:
Read (s, *, iostat=ios) num
1
Error: Data transfer element at (1) cannot be polymorphic unless
it is processed by a defined input/output procedure
这是我写的子程序。
Subroutine converts_str_to_num &
( &
s, num, &
fmt, wrn &
)
Character (len=*), Intent (in) :: s
Character (len=*), Intent (in), Optional :: fmt
Class (*) :: num
Character (len=*), Intent (inout), Optional :: wrn
Integer :: ios
Character (len=65) :: frmt
!!$ Reads contents of s and puts value in i.
If (Present (fmt)) Then
frmt = "(" // Trim (fmt) // ")"
Read (s, frmt, iostat=ios) num
Else
Read (s, *, iostat=ios) num
End If
End Subroutine converts_str_to_num
答
要整理评论,我会提供一个答案。
错误消息很明显:除非列表由定义的输入/输出处理,否则输入/输出列表中不能有多态变量。这是Fortran 2008中的9.6.3.5。class(*) num
是(无限制)多态。
现在,对于多态的派生类型,您可以定义这样一个定义的输入/输出过程,但这算作很多工作,并且gfortran当然不支持这个概念。此外,你不能为内在的类型做到这一点。这些因素意味着你必须处理输入列表中的非多态变量。
当然,可以使用泛型来避免多态性,但替代方案(因为它适用于所有多态)是使用select type
构造。为简单起见,忽略表式和显式格式的情况:
select type (assoc => num)
type is (int)
Read (s, *, iostat=ios) assoc
type is (real)
...
type is (...)
class default
error stop "Oh noes!"
end select
我在选择类型使用的关联名称来解决你的困惑的一个组成部分。如果你刚刚做了
select type(num)
type is (int)
Read (s, *, iostat=ios) num
end select
认为,“现在使用num
是好的:为什么呢?”那是因为num
里面的结构和num
不一样。至关重要的是,它不是多态,而是与type is
匹配的确切类型。
你的问题是什么?错误消息非常明确:除非使用定义的I/O,否则不能在I/O列表中使用多态变量。你是在“这是什么意思?”之后? – francescalus 2014-12-05 21:38:31
有没有解决方法,仍然有'类(*)'在那里? – Zeus 2014-12-05 21:39:50
@ChristopherDimech是的,使用'select type'构造并为所有想要处理的类型写一个case。 – casey 2014-12-05 21:40:54