如何移除Fortran扩展类型Namelist打印中的抽象类型前缀?
解决方案
gfortran 12.3.0在处理带继承关系的派生类型namelist输出时,默认会显式添加父类型的路径前缀,目前没有直接的编译选项可以关闭这一行为。你可以通过以下两种方式实现期望的输出格式:
方法一:手动格式化输出(推荐,实现简单)
直接绕过默认的namelist写入逻辑,手动按照目标格式输出参数:
program main use my_type implicit none type(the_settings) :: num namelist/nl_num/num open(unit=3,form='formatted',status='old',delim='apostrophe', file='example.nml') read(3,nl_num) close(3) ! 手动输出符合要求的namelist格式 write(*,'(A)') '&NL_NUM' write(*,'(A,I0,A)') ' NUM%A=', num%a, ' ,' write(*,'(A,I0,A)') ' NUM%B=', num%b, ' ,' write(*,'(A,I0,A)') ' NUM%SPECIAL_CASE%A=', num%special_case%a, ' ,' write(*,'(A,I0,A)') ' NUM%SPECIAL_CASE%B=', num%special_case%b, ' ,' write(*,'(A)') ' /' end program main
方法二:自定义类型格式化写过程(适合复杂类型场景)
为派生类型添加自定义的write(formatted)过程,控制组件的输出方式:
module my_type implicit none type, public, abstract :: settings integer :: a = 1 integer :: b = 0 contains procedure(settings_write), deferred :: write(formatted) end type settings abstract interface subroutine settings_write(this, unit, iotype, v_list, iostat, iomsg) import :: settings class(settings), intent(in) :: this integer, intent(in) :: unit character(*), intent(in) :: iotype integer, intent(in) :: v_list(:) integer, intent(out) :: iostat character(*), intent(inout) :: iomsg end subroutine settings_write end interface type, extends(settings), public :: settings_extended contains procedure :: write => settings_extended_write end type settings_extended type, extends(settings), public :: the_settings type(settings_extended) :: special_case contains procedure :: write => the_settings_write end type the_settings contains subroutine settings_extended_write(this, unit, iotype, v_list, iostat, iomsg) class(settings_extended), intent(in) :: this integer, intent(in) :: unit character(*), intent(in) :: iotype integer, intent(in) :: v_list(:) integer, intent(out) :: iostat character(*), intent(inout) :: iomsg write(unit, '(A,I0,A,I0,A)', iostat=iostat, iomsg=iomsg) & 'A=', this%a, ', B=', this%b, ', ' end subroutine settings_extended_write subroutine the_settings_write(this, unit, iotype, v_list, iostat, iomsg) class(the_settings), intent(in) :: this integer, intent(in) :: unit character(*), intent(in) :: iotype integer, intent(in) :: v_list(:) integer, intent(out) :: iostat character(*), intent(inout) :: iomsg integer :: ios write(unit, '(A)', iostat=ios, iomsg=iomsg) '&NL_NUM' if (ios /= 0) then iostat = ios return end if write(unit, '(A,I0,A)', iostat=ios, iomsg=iomsg) & ' NUM%A=', this%a, ' ,' if (ios /= 0) then iostat = ios return end if write(unit, '(A,I0,A)', iostat=ios, iomsg=iomsg) & ' NUM%B=', this%b, ' ,' if (ios /= 0) then iostat = ios return end if write(unit, '(A,I0,A)', iostat=ios, iomsg=iomsg) & ' NUM%SPECIAL_CASE%A=', this%special_case%a, ' ,' if (ios /= 0) then iostat = ios return end if write(unit, '(A,I0,A)', iostat=iostat, iomsg=iomsg) & ' NUM%SPECIAL_CASE%B=', this%special_case%b, ' ,' write(unit, '(A)') ' /' end subroutine the_settings_write end module my_type
使用这个模块后,原主程序的write(*,nl_num)语句即可输出符合要求的格式。
内容的提问来源于stack exchange,提问作者narsonalin
相关产品推荐
相关产品推荐

