2

I would like to create a type to contain an array of strings in Fortran without explicitly assigning lengths so I can return it from a function.

The following is my type:

type returnArr
    Character (*), dimension(4)  :: array
end type returnArr

The following is the function's signature:

type(returnArr) FUNCTION process(arr, mean, stdDev) result(j)

The following is where I try set the result:

j%array(1)= "Test"

But all I get is the following error:

Error: Character length of component ‘array’ needs to be a constant specification expression at (1)

How can I declare the type so that the strings may be of different length?

francescalus
  • 30,576
  • 16
  • 61
  • 96
Keagansed
  • 183
  • 1
  • 1
  • 13
  • Where is the answer to this question? I can't find it anywhere? @francescalus – Keagansed Aug 22 '18 at 14:22
  • I am looking specifically for how to return an array of strings. This question has not yet been asked. @francescalus – Keagansed Aug 22 '18 at 14:23
  • @HighPerformanceMark I was unable to return an array by simple saying Character(len=65), dimension(4) – Keagansed Aug 22 '18 at 14:25
  • To add to High Performance Mark's comments, container types can be useful for strings, but mainly if you want elements to be different lengths. – francescalus Aug 22 '18 at 14:25
  • @francescalus that worked but I would actually like the lengths to be different sizes so now I have the new problem of defining the type as character (*), dimension(4) ::array – Keagansed Aug 22 '18 at 14:35
  • That (having different lengths) you can't do as an array. You'll have to use your container type for that. Please edit the question so we can see where you are up to - it may simply be a minor change required. – francescalus Aug 22 '18 at 14:37
  • The question has been edited @francescalus – Keagansed Aug 22 '18 at 14:37

1 Answers1

2

A character component of a derived type may have either an explicit length, or it may have its length deferred. This latter is how one changes its value (by any of a number of means). It is also necessary to allow the flexibility of different lengths in an array of the derived type.

However, using len=* is not the correct way to say "deferred length" (it is "assumed length"). Instead, you may use len=: and make the component allocatable (or a pointer):

type returnArr
  Character (:), allocatable  :: char
end type returnArr

Then one may have an array of returnArr objects:

function process(arr, mean, stdDev) result(j)
  type(returnArr) :: j(4)
end function

Assignment such as as

  j(1)%char = "Test"

then relies on automatic allocation of the component char.

Note that now the function result is an array of that container type. We cannot do

function process(arr, mean, stdDev) result(j)
  character(:), allocatable :: j(:)
end function

and allocate j(1) to a length different from j(2) (etc.).

Similarly

type returnArr
  Character (:), allocatable  :: char(:)
end type returnArr

doesn't allow those char component elements to be of different lengths.

francescalus
  • 30,576
  • 16
  • 61
  • 96