fortranfortran90

How to automatically adjust string length in the A edit descriptor?


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.


Solution

  • 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