2017-06-20 70 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 

这里提到的基本 '键/值容器' 类缺乏任何散列/映射/类字典功能;查找只能通过遍历数据成员,直到找到密钥,然后获取相应的值。它确实只适用于中小型数据集。

相关问题