无法编译 returns 部分字符串的函数
Unable to compile function which returns parts of a string
我想在我的代码中使用以下函数。我希望它采用给定的字符串,删除所有前导零和 return 没有前导零的字符串。例如我给它 '00023'
它应该 return '23___'
(_
是 space)
我的代码中有这个功能:
function cut_zeros(string)
implicit none
character(5) :: cut_zeros, string
integer:: string_limit, i
string_limit = 5
do i= 1, string_limit
if (string(i)/='0') then
cut_zeros = string(i : string_limit)
exit
endif
enddo
end function cut_zeros
真不知道编译器出了什么问题。它提供了以下信息:
cut_zeros = string(i : string_limit)
1
Error: Syntax error in argument list at (1)
我还有一个问题?是否可以使函数假定长度?这样我就可以将任意长度的字符串传递给它?据我了解这是不可能的,因为函数的return值不能假设长度,对吗?
该错误消息实际上具有误导性。错误发生在上面一行:要比较第i个字符,需要使用string(i:i)
。如果将该行更改为
if (string(i:i)/='0') then
代码按预期运行。
对于你问题的第二部分,你可以使用假设长度的字符串!您可以简单地将 return 值的长度设置为输入字符串的长度:
function cut_zeros(string)
implicit none
character(*) :: string
character(len=len(string)) :: cut_zeros
integer:: string_limit, i
string_limit = len(string)
do i= 1, string_limit
if (string(i:i)/='0') then
cut_zeros = string(i : string_limit)
exit
endif
enddo
end function cut_zeros
这里选择了return字符串的长度,如果没有去掉零,它仍然有一个有效的长度。请注意,您将需要一个接口来处理假定长度的虚拟参数。
要将输出字符串裁剪到所需的确切长度,您需要可分配的字符串,但并非所有编译器都完全支持:
function cut_zeros(string)
implicit none
character(*) :: string
character(len=:),allocatable :: cut_zeros
integer:: string_limit, i
string_limit = len(string)
do i= 1, string_limit
if (string(i:i)/='0') then
allocate( character(len=string_limit-i+1) :: cut_zeros )
cut_zeros = string(i : string_limit)
exit
endif
enddo
end function cut_zeros
子字符串引用的语法需要分隔冒号,即您需要 string(i:i)
。如果你没有那个冒号,编译器认为该语法是一个函数引用(它知道它不是一个数组引用,因为你没有将 string
声明为一个数组)。
您不需要假定的长度函数。这样的事情存在,但它们是不合时宜的,最好被遗忘。您可能想要的是一个自动长度函数,其中函数结果的长度取决于输入。
FUNCTION cut_zeros(string)
CHARACTER(*), INTENT(IN) :: string
! The length of the function result is the same as the length
! of the argument.
CHARACTER(LEN(string)) :: cut_zeros
具有自动结果的函数在引用它的任何范围内都需要一个显式接口。最好将它放在一个模块中,然后使用该模块。
或者您可以使用 Fortran 的现有功能
CHARACTER(6) :: src = '002305'
CHARACTER(LEN(src)) :: dest
...
dest = src(SCAN(src,'123456789'):)
! now dest is '2305__'
这仅在第一个非 0
字符是另一个数字时有效,如果您有其他字符需要担心将第二个参数中使用的集合扩展到 SCAN
。
我想在我的代码中使用以下函数。我希望它采用给定的字符串,删除所有前导零和 return 没有前导零的字符串。例如我给它 '00023'
它应该 return '23___'
(_
是 space)
我的代码中有这个功能:
function cut_zeros(string)
implicit none
character(5) :: cut_zeros, string
integer:: string_limit, i
string_limit = 5
do i= 1, string_limit
if (string(i)/='0') then
cut_zeros = string(i : string_limit)
exit
endif
enddo
end function cut_zeros
真不知道编译器出了什么问题。它提供了以下信息:
cut_zeros = string(i : string_limit)
1
Error: Syntax error in argument list at (1)
我还有一个问题?是否可以使函数假定长度?这样我就可以将任意长度的字符串传递给它?据我了解这是不可能的,因为函数的return值不能假设长度,对吗?
该错误消息实际上具有误导性。错误发生在上面一行:要比较第i个字符,需要使用string(i:i)
。如果将该行更改为
if (string(i:i)/='0') then
代码按预期运行。
对于你问题的第二部分,你可以使用假设长度的字符串!您可以简单地将 return 值的长度设置为输入字符串的长度:
function cut_zeros(string)
implicit none
character(*) :: string
character(len=len(string)) :: cut_zeros
integer:: string_limit, i
string_limit = len(string)
do i= 1, string_limit
if (string(i:i)/='0') then
cut_zeros = string(i : string_limit)
exit
endif
enddo
end function cut_zeros
这里选择了return字符串的长度,如果没有去掉零,它仍然有一个有效的长度。请注意,您将需要一个接口来处理假定长度的虚拟参数。
要将输出字符串裁剪到所需的确切长度,您需要可分配的字符串,但并非所有编译器都完全支持:
function cut_zeros(string)
implicit none
character(*) :: string
character(len=:),allocatable :: cut_zeros
integer:: string_limit, i
string_limit = len(string)
do i= 1, string_limit
if (string(i:i)/='0') then
allocate( character(len=string_limit-i+1) :: cut_zeros )
cut_zeros = string(i : string_limit)
exit
endif
enddo
end function cut_zeros
子字符串引用的语法需要分隔冒号,即您需要 string(i:i)
。如果你没有那个冒号,编译器认为该语法是一个函数引用(它知道它不是一个数组引用,因为你没有将 string
声明为一个数组)。
您不需要假定的长度函数。这样的事情存在,但它们是不合时宜的,最好被遗忘。您可能想要的是一个自动长度函数,其中函数结果的长度取决于输入。
FUNCTION cut_zeros(string)
CHARACTER(*), INTENT(IN) :: string
! The length of the function result is the same as the length
! of the argument.
CHARACTER(LEN(string)) :: cut_zeros
具有自动结果的函数在引用它的任何范围内都需要一个显式接口。最好将它放在一个模块中,然后使用该模块。
或者您可以使用 Fortran 的现有功能
CHARACTER(6) :: src = '002305'
CHARACTER(LEN(src)) :: dest
...
dest = src(SCAN(src,'123456789'):)
! now dest is '2305__'
这仅在第一个非 0
字符是另一个数字时有效,如果您有其他字符需要担心将第二个参数中使用的集合扩展到 SCAN
。