如何在 A 编辑描述符中自动调整字符串长度?
How to automatically adjust string length in the A edit descriptor?
我正在尝试用 fortran 写一个字符串文件名:
WRITE(FILENAME,'(A27,I3.3,A1,I3.3,A3)') NAME,MYPR,'_',IBL,'.nc'
其中 NAME 是可变长度的字符串,MYPR
和 IBL
是整数。
我正在寻找一种可以动态编写格式的解决方案:
'(A27,I3.3,A1,I3.3,A3)',
其中 A27
将根据 NAME
的长度而变化。我单独尝试 'A'
但这导致了错误。我不确定这里有什么可能,因为许多文本甚至没有涵盖类似的问题。
将不胜感激。
显而易见的解决方案是使用格式字符串 '(A,I3.3,A1,I3.3,A3)'
,即仅使用 A
作为名称并让编译器选择正确的长度。这对我来说很完美。
正如@agentp 所建议的,您可能会看到由于字符串中的空格而导致的问题。这可以通过使用 trim(name)
去除尾随空格来解决,甚至可以使用 trim(adjustl(name))
来删除前导和尾随空格。该解决方案在下面的子例程 print1()
中给出。
另一种选择是动态生成格式字符串——毕竟,那也只是一个字符串。这非常麻烦,并且在您的情况下有点矫枉过正 - 参见 print2()
。
module test_mod
implicit none
contains
subroutine print1(NAME,MYPR,IBL)
character(len=*),intent(in) :: NAME
integer,intent(in) :: MYPR,IBL
WRITE(*,'(A,I3.3,A1,I3.3,A3)') trim(adjustl(NAME)),MYPR,'_',IBL,'.nc'
end subroutine
subroutine print2(NAME,MYPR,IBL)
character(len=*),intent(in) :: NAME
integer,intent(in) :: MYPR,IBL
character(len=128) :: fmt
write(fmt,*) len_trim(adjustl(NAME))
fmt = '(A'//trim(adjustl(fmt))//',I3.3,A1,I3.3,A3)'
WRITE(*,fmt) trim(adjustl(NAME)),MYPR,'_',IBL,'.nc'
end subroutine
end module
program test
use test_mod
call print1(' Testfile ', 1, 2)
call print2(' Testfile ', 1, 2)
end program
输出:
./a.out
Testfile001_002.nc
Testfile001_002.nc
我正在尝试用 fortran 写一个字符串文件名:
WRITE(FILENAME,'(A27,I3.3,A1,I3.3,A3)') NAME,MYPR,'_',IBL,'.nc'
其中 NAME 是可变长度的字符串,MYPR
和 IBL
是整数。
我正在寻找一种可以动态编写格式的解决方案:
'(A27,I3.3,A1,I3.3,A3)',
其中 A27
将根据 NAME
的长度而变化。我单独尝试 'A'
但这导致了错误。我不确定这里有什么可能,因为许多文本甚至没有涵盖类似的问题。
将不胜感激。
显而易见的解决方案是使用格式字符串 '(A,I3.3,A1,I3.3,A3)'
,即仅使用 A
作为名称并让编译器选择正确的长度。这对我来说很完美。
正如@agentp 所建议的,您可能会看到由于字符串中的空格而导致的问题。这可以通过使用 trim(name)
去除尾随空格来解决,甚至可以使用 trim(adjustl(name))
来删除前导和尾随空格。该解决方案在下面的子例程 print1()
中给出。
另一种选择是动态生成格式字符串——毕竟,那也只是一个字符串。这非常麻烦,并且在您的情况下有点矫枉过正 - 参见 print2()
。
module test_mod
implicit none
contains
subroutine print1(NAME,MYPR,IBL)
character(len=*),intent(in) :: NAME
integer,intent(in) :: MYPR,IBL
WRITE(*,'(A,I3.3,A1,I3.3,A3)') trim(adjustl(NAME)),MYPR,'_',IBL,'.nc'
end subroutine
subroutine print2(NAME,MYPR,IBL)
character(len=*),intent(in) :: NAME
integer,intent(in) :: MYPR,IBL
character(len=128) :: fmt
write(fmt,*) len_trim(adjustl(NAME))
fmt = '(A'//trim(adjustl(fmt))//',I3.3,A1,I3.3,A3)'
WRITE(*,fmt) trim(adjustl(NAME)),MYPR,'_',IBL,'.nc'
end subroutine
end module
program test
use test_mod
call print1(' Testfile ', 1, 2)
call print2(' Testfile ', 1, 2)
end program
输出:
./a.out
Testfile001_002.nc
Testfile001_002.nc