Vince W.
Vince W.

Reputation: 3785

better way to get a list of variable length strings in fortran

After much digging I've cooked up a home brew scheme for what amounts to a list of variable length strings in Fortran. Its really an array of a custom type that only has one member property which is a variable length string. The syntax is a little cumbersome and I'm wondering if there is a better way that I have not been able to find.

Here is what I have:

! scratch.f90
module string_list

  type t_string
     character(len=:), allocatable :: s
  end type

end module

program main
  use string_list

  implicit none

  integer i
  type(t_string), allocatable :: list(:)

  allocate(list(2))
  list(1)%s = "hi my name is"
  list(2)%s = "slim shady"

  do i=1,2
     print *, len(list(i)%s)
  end do

end program

compile with gfortran scratch.f90 -o scratch

then:

> ./scratch
13
10

Upvotes: 3

Views: 322

Answers (1)

Jonatan Öström
Jonatan Öström

Reputation: 2609

Like the comments suggest, your approach might be a good start. To make the syntax easier you could make some type-bound operators and procedures, for example like:

module string_list
    implicit none 
    type str
        character(:), allocatable :: s
    contains
        procedure :: assa, get, length
        generic :: assignment(=) => assa
        generic :: operator(-) => get
        generic :: l => length
    end type
contains
    subroutine assa(st,str1)
        class(str), intent(out) :: st
        character(*), intent(in) :: str1
        st%s = str1
    end
    function get(st1) result(str1)
        class(str), intent(in) :: st1
        character(:), allocatable :: str1
        str1 = st1%s
    end
    function length(st1) result(nn)
        class(str), intent(in) :: st1
        integer :: nn
        nn = len(st1%s)
    end
end 

program test
    use string_list, only: str
    implicit none
    type(str), dimension(:), allocatable :: stra
    allocate(stra(2))
    stra(1) = "hello "
    stra(2) = "fortran"
    print*, -stra(1)
    print*, -stra(1)//-stra(2)
    print*, stra(1)%l(), stra(2)%l()
    print*, len(-stra(1)), len(-stra(2))
end

The result is

 hello 
 hello fortran
           6           7
           6           7

This might not be the smartest design, I just tried something out of interest. Here I overloaded the - unitary operator to extract the actual string, and =for assignment, to avoid the %s syntax, and added a more convenient length-function.

Upvotes: 6

Related Questions