2014-12-05 297 views
1

我想要一個將數字 字符串的內容轉換爲數值類型(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 
+1

你的問題是什麼?錯誤消息非常明確:除非使用定義的I/O,否則不能在I/O列表中使用多態變量。你是在「這是什麼意思?」之後? – francescalus 2014-12-05 21:38:31

+0

有沒有解決方法,仍然有'類(*)'在那裏? – Zeus 2014-12-05 21:39:50

+4

@ChristopherDimech是的,使用'select type'構造併爲所有想要處理的類型寫一個case。 – casey 2014-12-05 21:40:54

回答

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匹配的確切類型。