在Fortran 90
程序中有许多嵌套子程序,我想将这些嵌套级别打印到压缩长度与级别成比例的文件中(即嵌套子程序中打印的信息的压痕比打电话的)。
将写入包括不同数据类型的其他信息(字符串,整数,......)。
我想到了不同的方法(在这个例子中,lev
是级别,只是在循环中构建,但在每个子例程中都会更新):
Program adaptIndent
INTEGER :: lev
CHARACTER (LEN=*), PARAMETER :: fmt1 = '(I1,'': ''A)'
CHARACTER (LEN=*), PARAMETER :: fmt2 = '(I2,'': ''A)'
DO lev=1,10
CALL printindent1
!CALL printindent2
!CALL printindent3
ENDDO
CONTAINS
SUBROUTINE printindent1 !convert everything (incl. indent and lev) to CHAR
CHARACTER(LEN=lev) :: indent
CHARACTER(LEN=2) :: strlev
WRITE(indent, '(A)') ' '
WRITE(strlev, '(I2)') lev
WRITE(*, '(A)') indent//TRIM(ADJUSTL(strlev))//': this is my level'
END SUBROUTINE printindent1
SUBROUTINE printindent2 !build a new format defining the indentation
CHARACTER(LEN=2) :: strlev
CHARACTER(LEN=20) :: fmtlev
WRITE(strlev, '(I2)') lev
WRITE(fmtlev, '(A)') '('//TRIM(ADJUSTL(strlev))//'X, A)'
WRITE(*, fmtlev) TRIM(ADJUSTL(strlev))//': this is my level'
END SUBROUTINE printindent2
SUBROUTINE printindent3 !add indent as CHAR to an existing format
CHARACTER(LEN=lev) :: indent
WRITE(indent, '(A)') ' '
IF(lev.LT.10) THEN
WRITE(*, fmt1(1:1)//'A,'//fmt1(2:)) indent, lev, 'this is my level'
ELSE
WRITE(*, fmt2(1:1)//'A,'//fmt2(2:)) indent, lev, 'this is my level'
ENDIF
END SUBROUTINE printindent3
END Program adaptIndent
这些解决方案的(所需)输出相同:
1: this is my level
2: this is my level
3: this is my level
4: this is my level
5: this is my level
6: this is my level
7: this is my level
8: this is my level
9: this is my level
10: this is my level
我的问题是,每次我执行有用的WRITE(*, *fmt*)
时,我都需要执行初步(和丑陋)步骤:
是否有比上述许多步骤更优雅的解决方案?
答案 0 :(得分:5)
答案 1 :(得分:2)
如果将字符串分配给比该字符长度短的字符,则会用空格填充。您可以使用它来轻松创建具有适当长度的缩进字符。
另外,我使用的所有编译器都理解I0
格式描述符,这意味着:根据需要使用尽可能多的字符。
以下是我的想法:
program printindent_test
implicit none
integer :: i
character(len=20) :: s
do i = 1, 10
call printindent("This is my level", i)
end do
contains
subroutine printindent(str, lev)
implicit none
character(len=*), intent(in) :: str
integer, intent(in) :: lev
character(len=lev) :: indent
indent = ''
write(*, '(A, I0, ": ", A)') indent, lev, str
end subroutine printindent
end program printindent_test
您不必进行相当多的转换以获取格式字符串。
write(fmtlev, "('('I2'X,I0,A)')") lev
write(*, fmtlev) lev, ": this is my level"
也会一样好。
如果您的编译器不了解I0
格式,您可以手动执行以下操作:
write(to_write, '(I2, ": ", A)') lev, str
write(*, '(2A)') indent, TRIM(ADJUSTL(to_write))
当然,您必须创建一个适当大小的新临时字符变量:
character(len=4+LEN_TRIM(str)) :: to_write