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