From: Jovan Cormac on
dpb wrote:

> BTW, one minor modification you could make in the above example if the
> strings _were_ in an array would be sotoo--
>
> program showit
> character(len=5):: str(3)
>
> str = (/ 'Hello', ' ', 'world' /)
>
> do i = 1, 3
> call doit(str(i)(:min(1,len_trim(str(i)))
> end do
> end
>
> This would pass the full length of the trimmed string but a blank string
> would be required to have a length of one instead of being of length zero.
>
> Not exactly "without additional processing" but the processing is on
> qualifying the input to the subroutine, not inside it. Of course, one
> could do the same thing inside the routine itself, but this way inside
> the routine the string array appears to have been variable length.
>
> The limitation this way as opposed to doing the same thing inside the
> routine is that only one element is in the routine at a time instead of
> the array.
>
> All depends, as Richard says, on what your needs really are.
>
> But to paraphrase another common answer when features or behavior in
> Fortran isn't what other language(s) might be is that Fortran CHARACTER
> variables/arrays aren't BASIC variable-length strings. :) (There's a lot
> of technical jargon that could be thrown in about what's different in
> implementation and why they behave as they do, but the upshot is it
> doesn't really matter when come right down to it--each is what it is).
>
> HTH...
>
> --


That is a good idea as well, thank you.

--
-- jovan
From: Richard Maine on
Jovan Cormac <limulus(a)gmx.net> wrote:

> Ron Shepard wrote:
>
> > So one workaround is to not use an array but rather to use scalar
> > arguments. You can write the subprogram so that it accepts some large
> > fixed number of scalar arguments (but not an unlimited number). You can
> > make the arguments optional,...
>
> That, sir, is a fantastic idea. I truthfully never though of that.

Way to go, Ron. Simple solution. ("Simple" in a good sense.) Hadn't
occurred to me that it would suffice for the need.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
From: dpb on
Jovan Cormac wrote:
> dpb wrote:
>
....
>> call doit(str(i)(:min(1,len_trim(str(i)))
....

> That is a good idea as well, thank you.

Well of course... <VBG>

Seems simpler/cleaner/neater to implement to me than handling optional
arguments (for this purpose, not as a generic statement) even if the
cleanup is in the input as can determine the size of the array on input
as well.

But I do recognize "simpler/cleaner/neater" is dependent upon the
beholder...

--
From: glen herrmannsfeldt on
dpb <none(a)non.net> wrote:
(big snip)

> The thing is, there isn't such an animal (at least as noted up thru F95)
> as a variable-length CHARACTER array defined as a varying allocated
> length of each element in the array; Fortran doesn't have "jagged" arrays.

Well, you can have an array of structures, with each having a pointer
to a different sized array. That gets you jagged arrays, but not
jagged character arrays. You could have such arrays of arrays
of CHARACTER*1, which isn't the same as of CHARACTER*(*).

> I'll let somebody who knows talk about anything later or you can dig
> through the Intel documentation for CHARACTER variables to see what it
> allows beyond F95, if anything.

I think Fortran 2008 allows ALLOCATABLE variables of CHARACTER*(:)
(I am not sure that is the way it is written, but it looks right)
such that you could build an array of structures containing such.

As far as I know, there are no constant structure constructors
comparable to the constant array constructors with (/ and /).

The C way (which I am not suggesting for Fortran) is an array
of pointers to null terminated character strings.

char *x[]={"these","are","strings"};

which could be used as:

#include <stdio.h>
#include <string.h>
int main() {
char *x[]={"these","are","strings"};
int i;
for(i=0;i<3;i++) printf("%d %s\n",strlen(x[i]),x[i]);
}

As for the OP, if you print the strings with the appropriately
generated run-time format, adding one blank after each element,
it shouldn't be so far off. If you need an unknown number of
trailing blanks, you can add an extra character to the end, and
then not count it before printing. Using non-advancing stream
I/O it should be pretty easy to print in a loop.

If one blank is enough, maybe:

write(*,'(1000(a,1x))')

as in:

character*5 x(3)
x=(/'this ','is ','it! '/)
write(*,'(1000(a,1x))') (trim(x(i)),i=1,3)
end

(Just wondering, why no elemental trim function...)

-- glen

From: dpb on
dpb wrote:
....

> do i = 1, 3
> call doit(str(i)(:min(1,len_trim(str(i)))
> end do
> end
>
> This would pass the full length of the trimmed string but a blank string
> would be required to have a length of one instead of being of length zero.
....

Well, it would if wrote max() instead of min(), anyway... :)

Dang, I hate it when I do that... :)

--
First  |  Prev  |  Next  |  Last
Pages: 1 2 3 4 5 6 7
Prev: many runs in one directory
Next: pressure and fortran