Fortran中动态分配字符串的问题

Fortran中动态分配字符串的问题,fortran,Fortran,我试图使用一个可变长度的字符串从NetCDF读取一些数据。为了使用NetCDF调用,我必须提供一个足够大的字符串来容纳数据。但是我遇到了问题 我用gfortran编译器的一种奇怪的行为来解释这个问题。至少我认为是这样,但也许这是Fortran 90的一个特性 以下是示例代码: program test implicit none integer clen,slen character(len=:), allocatable :: string clen

我试图使用一个可变长度的字符串从NetCDF读取一些数据。为了使用NetCDF调用,我必须提供一个足够大的字符串来容纳数据。但是我遇到了问题

我用gfortran编译器的一种奇怪的行为来解释这个问题。至少我认为是这样,但也许这是Fortran 90的一个特性

以下是示例代码:

    program test
    implicit none

    integer clen,slen
    character(len=:), allocatable :: string

    clen = 10
    allocate(character(len=clen) :: string)
    slen = len(string)

    write(6,*) 'clen,slen,dlen: ',clen,slen,len(string)
    string = ' '
    write(6,*) 'clen,slen,dlen: ',clen,slen,len(string)
    string = 'test'
    write(6,*) 'clen,slen,dlen: ',clen,slen,len(string)

    end
我希望对所有三个write语句都得到“10”,因为我分配的字符串大小为10

然而,我得到的是:

clen,slen,dlen:           10          10          10
clen,slen,dlen:           10          10           1
clen,slen,dlen:           10          10           4
似乎每次分配字符串时,字符串都会被重新分配。这不是我所期望的行为

我可能使用了gfortran(GNU Fortran(Debian 4.9.2-10)4.9.2)的过时版本。我的问题是:这种行为会随着编译器的更新版本而消失,还是Fortran 90的一个特性?如果这是一个特性,我如何避免它

似乎每次分配字符串时,字符串都会被重新分配

事实正是如此。我首先要注意的是,您的代码与Fortran 90不兼容:所谓的延迟长度字符变量是在Fortran 2003中引入的

当延迟长度字符变量是内在赋值的主题时(这是您在这里使用的
string=…
),它将采用右侧表达式的长度。这类似于

allocate
语句之后,
string
的长度为10,但是

string = ' '
右侧表达式的长度为1(单个空白)。这意味着
string
被取消分配,然后重新分配到这个新长度

与数组类似,可以使用子字符串保留赋值中左侧的长度:

string(:) = ' '
这样的子字符串不需要重新分配,您将看到固定长度字符串分配的常规规则(右边的填充或截断)


作为最后的评论,这种重新分配是分配的情况。当您将<代码>字符串传递到填充字符串的NETCDF过程中时,它不会进行这样的重新分配:NETCDF过程将认为哑参数不是递延长度。具有内在赋值的测试并不表示更广泛的行为。

您的代码与Fortran 90不兼容,而是与Fortran 2003兼容。Fortran 90非常陈旧过时,现在是2017年!