Fortran将字符串转换为数字

时间:2014-12-05 21:32:58

标签: class fortran

我想要一个转换数字内容的子程序 字符串到数字类型(int,real,double precision,real(real128))。

但是在尝试使用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

1 个答案:

答案 0 :(得分:4)

为了整理评论,我会提供答案。

错误消息是明确的:除非列表由定义的输入/输出处理,否则输入/输出列表中不能有多态变量。在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匹配的确切类型。