2017-06-20 69 views
2

我是Fortran的新手。我想開發以打印出指定變量信息用Fortran 95大派生類型爲簡化子程序,可以說我們有一個派生類型聲明和assigmnent如下:如何在Fortran中獲取派生類型組件的編號,名稱和值

type SubjectType 
    character(20) :: genre 
    character(20) :: maindude 
end type SubjectType 

type BookType 
    character(20) :: title 
    character(20) :: author 
    type(SubjectType) :: subject 

end type Booktype 

type(Booktype) :: Book 

Book%title = "Harry Potter" 
Book%author = "JK Rowling" 
Book%subject%genre = "Fantasy" 
Book%subject%maindude = "Ron Weasley" 

我想的輸出我的節目是一個文本文件,如下所示:

圖書%稱號,哈利·波特

書作家%,JK羅琳

圖書%受%流派,幻想

圖書%受%maindude,羅恩·韋斯萊

爲了實現這一點,我相信這是我需要做的:

  • 在每個級別確定派生類型字段數。對於在Booktype領域的實例數是3場數在Booktype%SubjectType將2
  • 想辦法到外地「數」涉及到的字段名(可能使用指針?)
  • 環覆蓋所有的字段號碼並獲取它們的名稱和值。

這裏我的問題是雙重的。首先,我的方法是正確的/是否會導致預期的結果?第二步如何完成此過程的第1步。也就是說,如何獲得每個級別派生類型的字段數?

+0

使用派生類型輸入/輸出(DTIO)-Fortran 2003-。 –

+1

不要這樣,不要把派生類型當成一個數組,這是通向地獄的路。 –

回答

1

我不是按照問題中提出的索引號來標識數據類型/字段,而是改編了一個非常基本的「鍵/值容器」類來完成任務。我們的想法是使用一對足夠通用的派生類型來創建任意數量的數據字段來表示各種圖書信息,並且您可以輕鬆訪問(和/或打印)。

! Start off with a generic DT to represent character string data fields. 
type :: Field 
    character(len=:), allocatable :: type !<- A category such as 'book' 
    character(len=:), allocatable :: key !<- Such as 'title' or 'author' 
    character(len=:), allocatable :: val !<- Such as 'Harry Potter' or 'JK Rowling' 
end type 

! It is simplest to create/use multiple Fields directly in the BookType. 
type :: BookType 
    character(len=8) :: type = 'BookType' 
    type(Field), dimension(:), allocatable :: fields 
    integer :: size = 0 
    contains 
     procedure, pass :: valueFromKey 
end type 

! Create a container to hold each BookType created. 
type :: BookCollection 
    type(BookType), dimension(:), allocatable :: book 
end type 

我將提供功能valueFromKey爲如何返回對應於給定鍵的值的例子。

function valueFromKey(self, key) 
    implicit none 
    class(BookType) :: self 
    character(*), intent(in) :: key 
    character(len=:), allocatable :: valueFromKey 
    integer :: i 
    logical :: val_is_found 

    val_is_found = .False. 
    do i = 1,self%size 
     if (trim(key) == self%fields(i)%key) then 
      valueFromKey = self%fields(i)%val 
      val_is_found = .True. 
      exit 
     endif 
    enddo 

    if (.not. val_is_found) then 
     valueFromKey = "None" 
    endif 
end function valueFromKey 

將上述所有代碼的一個模塊中。由於不需要回答問題並提供工作解決方案,因此我省去了一些幫助功能。不過,您會在下面的示例程序中看到其中的一個(newBook)。請注意,循環字段將打印所有現有數據,這可能因書而異。 OTH,要求valueFromKey中任何不在書本數據中的鍵都將返回字符串'None'。

! Example usage: 
program main 
    use BookModule 
    implicit none 
    integer :: i, j 
    character(len=6) :: num 
    type(BookCollection) :: MyBooks 

    allocate(MyBooks%book(2)) 
    MyBooks%book(1) = newBook(keys=['title', 'author', 'date', 'genre', 'lead'], values=["Harry Potter", "JK Rowling", "1997", "Fantasy", "Ron Weasley"]) 
    MyBooks%book(2) = newBook(keys=['title', 'author', 'lead'], values=["1984", "George Orwell", "Winston Smith"]) 

    print *, "LOOP OVER BOOK COLLECTION" 
    do i = 1, size(MyBooks%book) 
     write(num, '(i6)') i 
     print *, "Item ", adjustl(num) 
     do j = 1, MyBooks%book(i)%size 
      print *, MyBooks%book(i)%type, ", ", MyBooks%book(i)%fields(j)%type, ", ", MyBooks%book(i)%fields(j)%key, ", ", MyBooks%book(i)%fields(j)%val 
     enddo 
     print * 
    enddo 

    print *, "GET FIELD VALUE FROM KEY" 
    print *, " Title: ", MyBooks%book(1)%valueFromKey('title') 
    print *, " Author: ", MyBooks%book(1)%valueFromKey('author') 
    print *, " Date: ", MyBooks%book(1)%valueFromKey('date') 
    print * 
    print *, " Title: ", MyBooks%book(2)%valueFromKey('title') 
    print *, " Author: ", MyBooks%book(2)%valueFromKey('author') 
    print *, " Date: ", MyBooks%book(2)%valueFromKey('date') 
end program main 

輸出示例:

LOOP OVER BOOK COLLECTION 
Item 1 
BookType, book, title, Harry Potter 
BookType, book, author, JK Rowling 
BookType, book, date, 1997 
BookType, subject, genre, Fantasy 
BookType, subject, lead, Ron Weasley 

Item 2 
BookType, book, title, 1984 
BookType, book, author, George Orwell 
BookType, subject, lead, Winston Smith 

GET FIELD VALUE FROM KEY 
    Title: Harry Potter 
    Author: JK Rowling 
    Date: 1997 

    Title: 1984 
    Author: George Orwell 
    Date: None 

這裏提到的基本 '鍵/值容器' 類缺乏任何散列/映射/類字典功能;查找只能通過遍歷數據成員,直到找到密鑰,然後獲取相應的值。它確實只適用於中小型數據集。

相關問題