Fortran:在主程序中初始化未知长度的字符串

Fel*_*lix 5 string fortran initialization character

我有一个字符串,我想用子例程调用中的意图(输出)数据进行初始化。我看起来有点像这样:

character(*) :: path
call get_path(path)
Run Code Online (Sandbox Code Playgroud)

编译器告诉我:

错误:假定字符长度为 (1) 的实体必须是虚拟参数或 PARAMETER

该结构在子程序中运行良好,但在主程序中失败。是否可以在不知道路径变量长度的情况下初始化路径变量?

编辑:我已经尝试过但失败了。

character(99) :: path_temp
character(:), allocatable :: path
call get_path(path_temp)
allocate(path(len(trim(path_temp))))
Run Code Online (Sandbox Code Playgroud)

错误:(1) 处可分配标量的形状规范

我不明白为什么编译器认为路径是标量。


返回具有假定长度的字符的函数显然是非法的。

character(*) function get_path ()
    get_path         =     '/path/to/folder/'
end function get_path
Run Code Online (Sandbox Code Playgroud)

错误: (1) 处的字符值模块过程“get_path”不得假定长度


什么有效但让我头疼,因为我发现它非常糟糕的风格是给路径一个疯狂的长度并在每次使用时修剪它。我认为我的编译器在处理可分配字符串时遇到问题,因为它不是最新的(mpif90)。不确定它是否支持它们。

fra*_*lus 6

许多要点都包含在注释链接的其他答案中,例如“假定长度”需要什么以及如何分配标量延迟长度字符变量。

在给出具体答案之前,我会指出两件事。

对延迟长度可分配标量字符变量的内在赋值会导致(如果需要)将该变量分配给表达式的长度。那是

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
Run Code Online (Sandbox Code Playgroud)

可以替换为

character(99) :: path_temp
character(:), allocatable :: path

call get_path(path_temp)
path = TRIM(path_temp)
Run Code Online (Sandbox Code Playgroud)

另一件需要注意的事情是相当迂腐的,但错误地使用术语可能会阻碍搜索。 Fortran 中的初始化意味着一些特定的东西,但在这里不适用。

根据编译器错误消息,您说具有假定长度字符结果的函数显然是非法的

错误: (1) 处的字符值模块过程“get_path”不得假定长度

这并不完全正确:在某些情况下,字符函数结果可以(目前 - 这是现代 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())
...
Run Code Online (Sandbox Code Playgroud)

由于您似乎完全控制了子例程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
Run Code Online (Sandbox Code Playgroud)