I'm trying to write a string filename in fortran using:
WRITE(FILENAME,'(A27,I3.3,A1,I3.3,A3)') NAME,MYPR,'_',IBL,'.nc'
where NAME is a string of variable lengths, and MYPR
and IBL
are integers.
I'm searching for a solution where I can dynamically write the format:
'(A27,I3.3,A1,I3.3,A3)',
where A27
will change depending on the length of NAME
. I've tried 'A'
alone but this caused an error. I'm not sure of what is possible here as many texts do not even cover something similar issues.
Would appreciate some ideas.
The obvious solution would be to use the format string '(A,I3.3,A1,I3.3,A3)'
, i.e. using just A
for the name and letting the compiler choose the correct length. This is working perfectly for me.
As @agentp suggested, you might see issues due to whitespaces in the string. This might be resolved by using trim(name)
to get rid of trailing whitespace, or even trim(adjustl(name))
which removes both leading and trailing whitespace. This solution is given below in subroutine print1()
.
The other option would be to generate the format string dynamically - after all, that is just a string as well. This is quite cumbersome, and an overkill in your situation - see 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
Output:
./a.out
Testfile001_002.nc
Testfile001_002.nc