3

I am writing a function to return a string

function doc () Result s
character (Len=65) :: s
...
end function

Is it possible to have a variable length string, where I can allocate the length of the string being returned. I know I can do it using a subroutine, but not for a function.

Function discl (nm) Result (s)

Character (Len=:), Allocatable :: s 
Character (Len=*), Intent (In) :: nm

Integer :: n
Character (Len=65) :: stamp
stamp = "Thu May  7 15:13:48 BST 2015" 

n = Len_trim (stamp)
Allocate (Character (n) :: s)
s = Trim (fstamp) 

End Subroutine discl
Zeus
  • 1,485
  • 1
  • 17
  • 33

2 Answers2

8

It is the same for a subroutine and for a function. Only the header differs, but you can use the result variable as any other variable. My favourite example is the conversion of an integer to a string

  function itoa(i) result(res)
    character(:),allocatable :: res
    integer,intent(in) :: i
    character(range(i)+2) :: tmp
    write(tmp,'(i0)') i
    res = trim(tmp)
  end function

the result variable is allocated on assignment. You could use an allocate statement before the assignment, but that is redundant.

  • I disagree with your last statement. In my experience, allocation by assignment is asking for trouble! You should *always* allocate before an assignment and deactivate that particular feature at compile-time. – Alexander Vogt May 07 '15 at 14:16
  • 3
    I don't bother, it is standard conforming the same way as automatic deallocation from F95 and even Intel is thinking about making it the default. – Vladimir F Героям слава May 07 '15 at 14:19
  • What sort of problems have you encountered when you don't allocate? – Zeus May 07 '15 at 14:19
  • @Zeus See http://stackoverflow.com/questions/23618034/mpi-err-buffer-when-performing-mpi-i-o – Vladimir F Героям слава May 07 '15 at 14:20
  • I would agree with Vlad that one should use automatic allocation and deallocation whenever possible. – Zeus May 07 '15 at 14:21
  • 1
    If you accidentally assign an array with mismatching shape you will not get an error message but the array will silently get re-allocated. This makes de-bugging very tricky. – Alexander Vogt May 07 '15 at 14:22
  • @AlexanderVogt You can always do `A(:) = gjslkj`. – francescalus May 07 '15 at 14:30
  • @francescalus I don't quite get that :( The difficulty is realizing that the assignment causes the error. How does your suggestion help finding this error? – Alexander Vogt May 07 '15 at 14:41
  • @AlexanderVogt `A(:)=gjslkj` will have the same effect as `A=gjslkj` when A is not automatically re-allocated (either as not allocatable or through non-Fortran (or pre-F2003) compilation). Is your concern that someone who does not know the rules will have problems? If so, if they have problems once that take an age to solve, they'll pretty surely remember the next time. – francescalus May 07 '15 at 14:51
7

You can use allocatable strings for this purpose:

module str_mod
  implicit none

contains 

function str2str(str) result(s)
  implicit none
  character(len=*),intent(in)   :: str
  character(len=:),allocatable  :: s

  allocate( character(len=2*len(str)) :: s )
  s = str // str
end function

end module

program test
  use str_mod
  print *,str2str('test')
end program
Alexander Vogt
  • 17,879
  • 13
  • 52
  • 68
  • 1
    Even with the discussion about the merits of the `allocate` statement in another answer, it's a good reminder _how_ to allocate a deferred length character. – francescalus May 07 '15 at 14:33