如何在Fortran中获取派生类型组件的编号、名称和值
我不熟悉Fortran。我想开发一个子程序,将分配的变量信息打印到Fortran 95中的大型派生类型。为了简化,假设我们有一个派生类型声明和assignment,如下所示:如何在Fortran中获取派生类型组件的编号、名称和值,fortran,fortran95,Fortran,Fortran95,我不熟悉Fortran。我想开发一个子程序,将分配的变量信息打印到Fortran 95中的大型派生类型。为了简化,假设我们有一个派生类型声明和assignment,如下所示: type SubjectType character(20) :: genre character(20) :: maindude end type SubjectType type BookType character(20) :: title character(20) :: auth
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"
我希望我的程序的输出是一个文本文件,如下所示:
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罗琳
书籍%主题%流派,幻想
书籍%subject%main都德,罗恩·韦斯莱
为了实现这一目标,我相信这就是我需要做的:
- 确定每个级别的派生类型中的字段数。例如,
图书类型中的字段数为3。
中的字段数应为2Booktype%SubjectType
- 找到将字段“编号”与字段名称关联的方法(可能使用指针?)
- 循环遍历所有字段号并获取它们的名称和值
我的问题有两个。首先,我的方法是否正确/是否会导致预期结果?其次,我如何完成此过程的步骤1。也就是说,我如何在每个级别获得派生类型中的字段数?我采用了一个非常基本的“键/值容器”类来完成任务,而不是像问题中建议的那样通过索引号来标识数据类型/字段。其思想是使用两个派生类型,这些派生类型足够通用,可以重用,以创建任意数量的数据字段来表示各种图书信息,并且可以轻松访问(和/或打印) 将上述所有代码放在一个模块中。我省略了几个助手函数,因为它们不是回答问题和提供有效解决方案所必需的。不过,您将在下面的示例程序中看到其中一个(
newBook
)。请注意,循环域打印所有现有数据,这些数据可能因书籍而异。另外,对于任何不在书本数据中的键,请求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
1此处提到的基本“key/value container”类缺少任何类似于散列/映射/字典的功能;查找工作仅通过在数据成员上循环,直到找到键,然后获取相应的值。它实际上只适用于中小型数据集 使用派生类型输入/输出(DTIO)-Fortran 2003-。不要这样做,不要将派生类型视为数组,这是一条地狱之路。
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