Fortran:在主程序中初始化长度未知的字符串
Fortran: Initialize character string with unknown length in main program
我有一个字符串,我想用来自子例程调用的 intent(out) 数据进行初始化。我有点像:
character(*) :: path
call get_path(path)
编译器告诉我:
Error: Entity with assumed character length at (1) must be a dummy
argument or a PARAMETER
该构造在子程序中运行良好,但在主程序中失败。是否可以在不知道长度的情况下初始化路径变量?
编辑:我已经尝试过但失败了。
character(99) :: path_temp
character(:), allocatable :: path
call get_path(path_temp)
allocate(path(len(trim(path_temp))))
Error: Shape specification for allocatable scalar at (1)
我不明白为什么编译器认为路径是标量。
一个returns假定长度的字符显然是非法的函数。
character(*) function get_path ()
get_path = '/path/to/folder/'
end function get_path
Error: Character-valued module procedure 'get_path' at (1) must not be assumed length
什么有效但让我头疼,因为我发现它非常糟糕的风格是给路径一个疯狂的长度并且 trim 每次使用它。我认为我的编译器在处理可分配字符串时遇到了问题,因为它不是最新的 (mpif90)。不确定它是否支持它们。
许多要点都包含在评论链接的其他答案中,例如 "assumed length" 需要什么以及如何分配 scalar 延迟长度字符变量。
在得出具体答案之前,我要指出两点。
对延迟长度可分配标量字符变量的内部赋值会导致(如果需要)将该变量分配给表达式的长度。即
character(99) :: path_temp
character(:), allocatable :: path
call get_path(path_temp)
allocate(character(len(trim(path_temp))) :: path) ! Note the correct form
path = TRIM(path_temp) ! Or path(:)=path_temp
可以替换为
character(99) :: path_temp
character(:), allocatable :: path
call get_path(path_temp)
path = TRIM(path_temp)
还有一点要注意,比较迂腐,但用词不当可能会妨碍查找。 Initialization 在 Fortran 中意味着一些特定的东西在这里不适用。
根据编译器错误消息,您说具有假定长度字符结果的函数显然是非法的
Error: Character-valued module procedure 'get_path' at (1) must not be assumed length
这不完全正确:在某些情况下,字符函数结果可以(目前 - 它是现代 Fortran 的一个过时的特性)具有假定的长度。但是,它们必须是外部函数。看到编译器抱怨模块过程(然后不是外部过程)。
也就是说,假设长度的字符结果对您没有帮助。结果的长度仍然必须从某些东西中假定,并且某些东西不在函数体中,而是在作用域中定义外部函数的声明。
类似
implicit none
character(99) get_path ! The length of the get_path result is assumed from here
character(:), allocatable :: path
path = TRIM(get_path())
...
由于您似乎可以完全控制子例程 get_path
,因此有最后一个值得回答的评论。您可以直接分配参数。
subroutine get_path(path)
character(:), allocatable, intent(out) :: path
path = '/path/to/folder/' ! Allocation through intrinsic assignment
path = TRIM(path) ! In general, if it's likely to have trailing blanks
end subroutine
我有一个字符串,我想用来自子例程调用的 intent(out) 数据进行初始化。我有点像:
character(*) :: path
call get_path(path)
编译器告诉我:
Error: Entity with assumed character length at (1) must be a dummy argument or a PARAMETER
该构造在子程序中运行良好,但在主程序中失败。是否可以在不知道长度的情况下初始化路径变量?
编辑:我已经尝试过但失败了。
character(99) :: path_temp
character(:), allocatable :: path
call get_path(path_temp)
allocate(path(len(trim(path_temp))))
Error: Shape specification for allocatable scalar at (1)
我不明白为什么编译器认为路径是标量。
一个returns假定长度的字符显然是非法的函数。
character(*) function get_path ()
get_path = '/path/to/folder/'
end function get_path
Error: Character-valued module procedure 'get_path' at (1) must not be assumed length
什么有效但让我头疼,因为我发现它非常糟糕的风格是给路径一个疯狂的长度并且 trim 每次使用它。我认为我的编译器在处理可分配字符串时遇到了问题,因为它不是最新的 (mpif90)。不确定它是否支持它们。
许多要点都包含在评论链接的其他答案中,例如 "assumed length" 需要什么以及如何分配 scalar 延迟长度字符变量。
在得出具体答案之前,我要指出两点。
对延迟长度可分配标量字符变量的内部赋值会导致(如果需要)将该变量分配给表达式的长度。即
character(99) :: path_temp
character(:), allocatable :: path
call get_path(path_temp)
allocate(character(len(trim(path_temp))) :: path) ! Note the correct form
path = TRIM(path_temp) ! Or path(:)=path_temp
可以替换为
character(99) :: path_temp
character(:), allocatable :: path
call get_path(path_temp)
path = TRIM(path_temp)
还有一点要注意,比较迂腐,但用词不当可能会妨碍查找。 Initialization 在 Fortran 中意味着一些特定的东西在这里不适用。
根据编译器错误消息,您说具有假定长度字符结果的函数显然是非法的
Error: Character-valued module procedure 'get_path' at (1) must not be assumed length
这不完全正确:在某些情况下,字符函数结果可以(目前 - 它是现代 Fortran 的一个过时的特性)具有假定的长度。但是,它们必须是外部函数。看到编译器抱怨模块过程(然后不是外部过程)。
也就是说,假设长度的字符结果对您没有帮助。结果的长度仍然必须从某些东西中假定,并且某些东西不在函数体中,而是在作用域中定义外部函数的声明。
类似
implicit none
character(99) get_path ! The length of the get_path result is assumed from here
character(:), allocatable :: path
path = TRIM(get_path())
...
由于您似乎可以完全控制子例程 get_path
,因此有最后一个值得回答的评论。您可以直接分配参数。
subroutine get_path(path)
character(:), allocatable, intent(out) :: path
path = '/path/to/folder/' ! Allocation through intrinsic assignment
path = TRIM(path) ! In general, if it's likely to have trailing blanks
end subroutine