Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Io 如何使用名称列表在派生类型中写入可分配数组?_Io_Fortran_Fortran2003_Derived Types - Fatal编程技术网

Io 如何使用名称列表在派生类型中写入可分配数组?

Io 如何使用名称列表在派生类型中写入可分配数组?,io,fortran,fortran2003,derived-types,Io,Fortran,Fortran2003,Derived Types,我在使用名称列表编写嵌套在派生类型中的可分配数组时遇到问题。下面是一个简单的例子。如何修改程序,使可分配数组在派生类型中工作,就好像它没有嵌套一样 program test implicit none type struct_foo integer, allocatable :: nested_bar(:) end type struct_foo integer, allocatable :: bar(:) type(struct_f

我在使用名称列表编写嵌套在派生类型中的可分配数组时遇到问题。下面是一个简单的例子。如何修改程序,使可分配数组在派生类型中工作,就好像它没有嵌套一样

program test

    implicit none

    type struct_foo
        integer, allocatable :: nested_bar(:)
    end type struct_foo

    integer, allocatable :: bar(:)
    type(struct_foo) :: foo
    ! namelist / list / foo, bar
    namelist / list / bar

    allocate(bar(5))
    bar = [1:5]

    allocate(foo%nested_bar(5))
    foo%nested_bar=[1:5]

    write(*,list)

end program test
在名称列表中注释掉foo后,它工作正常,产生输出:

 &LIST
 BAR     =           1,           2,           3,           4,           5
 /
包含foo后,程序无法编译:

>> ifort -traceback test_1.f90 -o test && ./test
test_1.f90(20): error #5498: Allocatable or pointer derived-type fields require a user-defined I/O procedure.
    write(*,list)
--------^
compilation aborted for test_1.f90 (code 1)

正如错误消息所述,您需要提供一个用户定义的派生类型I/O(UDDTIO)过程。这对于具有可分配或指针组件的任何对象的输入/输出都是必需的

派生类型的对象在文件中的格式完全由UDDTIO过程控制

下面是一个使用非常简单的输出格式的示例。通常,实现名称列表输出的UDDTIO过程将使用与名称列表输出的其他方面一致的输出格式,并且通常还会有一个相应的UDDTIO过程,该过程随后能够读回格式化的结果

module foo_mod
  implicit none

  type struct_foo
    integer, allocatable :: nested_bar(:)
  contains
    procedure, private :: write_formatted
    generic :: write(formatted) => write_formatted
  end type struct_foo
contains
  subroutine write_formatted(dtv, unit, iotype, v_list, iostat, iomsg)
    class(struct_foo), intent(in) :: dtv
    integer, intent(in) :: unit
    character(*), intent(in) :: iotype
    integer, intent(in) :: v_list(:)
    integer, intent(out) :: iostat
    character(*), intent(inout) :: iomsg

    integer :: i

    if (allocated(dtv%nested_bar)) then
      write (unit, "(l1,i10,i10)", iostat=iostat, iomsg=iomsg)   &
          .true.,  &
          lbound(dtv%nested_bar, 1),  &
          ubound(dtv%nested_bar, 1)
      if (iostat /= 0) return
      do i = 1, size(dtv%nested_bar)
        write (unit, "(i10)", iostat=iostat, iomsg=iomsg)  &
            dtv%nested_bar(i)
        if (iostat /= 0) return
      end do
      write (unit, "(/)", iostat=iostat, iomsg=iomsg)
    else
      write (unit, "(l1,/)", iostat=iostat, iomsg=iomsg) .false.
    end if
  end subroutine write_formatted
end module foo_mod

program test
  use foo_mod

  implicit none

  integer, allocatable :: bar(:)
  type(struct_foo) :: foo
  namelist / list / foo, bar

  allocate(bar(5))
  bar = [1:5]

  allocate(foo%nested_bar(5))
  foo%nested_bar=[1:5]

  write (*,list)
end program test

使用UDDTIO显然需要一个实现Fortran 2003语言功能的编译器。

谢谢,伊恩。该语言不允许直接从派生类型中的可分配项写入名称列表,这有什么特殊原因吗?可分配组件的分配状态(或指针组件的语义和关联状态)没有明显的格式表示。也许组件总是被分配-在这种情况下,不需要表示一个未分配的条件,也许下界永远是一个,等等。当考虑具有递延长度参数的多态组件和组件时,它会变得更加复杂。再次感谢,伊恩。最后一个问题:为什么写(unit,“(i10)”,iostat=iostat,iomsg=iomsg)在写i10之后不产生换行符?如何在UDDTIO中实现换行?子输入/输出语句(作为UDDTIO处理的一部分调用的语句)不会自动前进到下一条记录-它们始终被视为不前进(advance='NO')输入/输出语句。有没有办法用子i/o生成换行符?能否告诉我们您使用的是哪种编译器?ifort(ifort)15.0.3 20150408