! Solution 5/7
      module string_type
         public :: assignment(=), operator(//), c_to_s_assign,   &
                   s_to_c_assign, string_len,  string_concat,  len
         intrinsic len
         type, public :: string
            integer             :: length
            character(len=80)   :: string_data
         end type string
         interface assignment(=)
            module procedure c_to_s_assign, s_to_c_assign
         end interface
         interface len
            module procedure string_len
         end interface
         interface operator(//)
            module procedure string_concat
         end interface
      contains
         subroutine c_to_s_assign(s, c)
            type (string), intent(out)   :: s
            character(len=*), intent(in) :: c
            s%string_data = c
            s%length = len(c)
            if (s%length > 80) then
               s%length = 80
            end if
         end subroutine c_to_s_assign
         subroutine s_to_c_assign(c, s)
            character(len=*), intent(out) :: c
            type (string), intent(in)     :: s
            c = s%string_data(1:s%length)
         end subroutine s_to_c_assign
         function string_len(s) result(sl)
            type(string), intent(in) :: s
            integer                  :: sl
            sl = s%length
         end function string_len
         function string_concat(s1, s2) result(sc)
            type (string), intent(in) :: s1, s2
            type (string)             :: sc
            sc%string_data = s1%string_data(1:s1%length) // &
                             s2%string_data(1:s2%length)
            sc%length = s1%length + s2%length
            if (sc%length > 80) then
               sc%length = 80
            end if
         end function string_concat
      end module string_type
