For Programmers: Free Programming Magazines  


Home > Archive > Fortran > March 2006 > Character String Dynamic Allocation









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Character String Dynamic Allocation
gary.l.scott@lmco.com

2006-03-24, 7:07 pm

Hi,

A rich text entry field can be set to limit the number of characters
typed by a user, however if OLE objects are allowed to be pasted to the
field, it can exceed the size of a statically allocated string assigned
to retrieve the final edited content. The particular third party API
being used requires a string, not an array. Since you can't
dynamically allocate a string in F95 (so that I can size it to fit the
actual rich text content after the user finishes editing), is there a
way to allocate a character(len=1) array and type cheat (equivalence,
integer pointers) (or other method)? Both approaches failed but I fear
that there's something I'm overlooking.

robert.corbett@sun.com

2006-03-24, 10:00 pm


gary.l.scott@lmco.com wrote:
> Hi,
>
> A rich text entry field can be set to limit the number of characters
> typed by a user, however if OLE objects are allowed to be pasted to the
> field, it can exceed the size of a statically allocated string assigned
> to retrieve the final edited content. The particular third party API
> being used requires a string, not an array. Since you can't
> dynamically allocate a string in F95 (so that I can size it to fit the
> actual rich text content after the user finishes editing), is there a
> way to allocate a character(len=1) array and type cheat (equivalence,
> integer pointers) (or other method)? Both approaches failed but I fear
> that there's something I'm overlooking.


I don't understand what you mean. Doesn't the following program
dynamically allocate a string?

FUNCTION ASTRING(N)
POINTER ASTRING
CHARACTER*(N) ASTRING
ALLOCATE (ASTRING)
END

SUBROUTINE SUBR(N)
INTERFACE
FUNCTION ASTRING(N)
POINTER ASTRING
CHARACTER*(N) ASTRING
END FUNCTION
END INTERFACE

CHARACTER*(N), POINTER :: PSTRING
PSTRING => ASTRING(N)
PSTRING = REPEAT('A', N)
PRINT *, PSTRING
END

PROGRAM MAIN
READ *, N
CALL SUBR(N)
END

Bob Corbett

Gary L. Scott

2006-03-25, 4:00 am

robert.corbett@sun.com wrote:
> gary.l.scott@lmco.com wrote:
>
>
>
> I don't understand what you mean. Doesn't the following program
> dynamically allocate a string?
>
> FUNCTION ASTRING(N)
> POINTER ASTRING
> CHARACTER*(N) ASTRING
> ALLOCATE (ASTRING)
> END
>
> SUBROUTINE SUBR(N)
> INTERFACE
> FUNCTION ASTRING(N)
> POINTER ASTRING
> CHARACTER*(N) ASTRING
> END FUNCTION
> END INTERFACE
>
> CHARACTER*(N), POINTER :: PSTRING
> PSTRING => ASTRING(N)
> PSTRING = REPEAT('A', N)
> PRINT *, PSTRING
> END
>
> PROGRAM MAIN
> READ *, N
> CALL SUBR(N)
> END
>
> Bob Corbett
>

Seems to work. Thanks. I was declaring the string with the
"allocatable" attribute which didn't work. I missed something somewhere
apparently.

--

Gary Scott
mailto:garyscott@ev1.net

Fortran Library: http://www.fortranlib.com

Support the Original G95 Project: http://www.g95.org
-OR-
Support the GNU GFortran Project: http://gcc.gnu.org/fortran/index.html

Why are there two? God only knows.


If you want to do the impossible, don't hire an expert because he knows
it can't be done.

-- Henry Ford
robert.corbett@sun.com

2006-03-25, 4:00 am


Gary L. Scott wrote:

> Seems to work. Thanks. I was declaring the string with the
> "allocatable" attribute which didn't work. I missed something somewhere
> apparently.


Fortran 95 does not allow scalars to have the ALLOCATABLE
attribute. Fortran 2003 does.

Bob Corbett

Gary L. Scott

2006-03-25, 7:01 pm

robert.corbett@sun.com wrote:
> Gary L. Scott wrote:
>
>
>
>
> Fortran 95 does not allow scalars to have the ALLOCATABLE
> attribute. Fortran 2003 does.
>
> Bob Corbett
>

Since the API call is in the program main and "An automatic object is
invalid in a main program.", I guess that means I must make a wrapper
for the 3rd party API which is already a wrapper for a wrapper. Sheesh,
what a kludge.

--

Gary Scott
mailto:garyscott@ev1.net

Fortran Library: http://www.fortranlib.com

Support the Original G95 Project: http://www.g95.org
-OR-
Support the GNU GFortran Project: http://gcc.gnu.org/fortran/index.html

Why are there two? God only knows.


If you want to do the impossible, don't hire an expert because he knows
it can't be done.

-- Henry Ford
Gary L. Scott

2006-03-25, 7:01 pm

Gary L. Scott wrote:

> robert.corbett@sun.com wrote:
>
> Since the API call is in the program main and "An automatic object is
> invalid in a main program.", I guess that means I must make a wrapper
> for the 3rd party API which is already a wrapper for a wrapper. Sheesh,
> what a kludge.
>

Here is a tentative solution. It is VERY scary. Since I need access to
the storage in the main, this works. The scary part is that I can
access beyond the allocated size because string length intrinsics are
unaware. I must be careful to pass an explicit length or substring.
Given the requirement to access the storage in the program main, what
other solution is there?
!
! A test program
!
module string

contains

function aString(N)

implicit none

integer :: n

character(n), pointer :: aString

allocate(aString)

end function

end module

program test

use string

implicit none

integer :: n

character(2147483647), pointer :: pString !Maximum possible size of
rich edit field

open(10,file="c:\data.txt")
!
! Value of N would be determined by query of rich edit field via 3rd
party API
!
n=22

pString => aString(N)

pString(1:n) = "0233456709101112131415"

write(10,'(a,a)')'pString=',pString(1:n)


call ThirdPartyAPI(pString(1:n))

end program

subroutine ThirdPartyAPI(charval)

implicit none

character(*) :: charval

write(10,'(a,i0)')'ArgLen=',len(charval)


return

end subroutine

--

Gary Scott
mailto:garyscott@ev1.net

Fortran Library: http://www.fortranlib.com

Support the Original G95 Project: http://www.g95.org
-OR-
Support the GNU GFortran Project: http://gcc.gnu.org/fortran/index.html

Why are there two? God only knows.


If you want to do the impossible, don't hire an expert because he knows
it can't be done.

-- Henry Ford
Joost

2006-03-25, 7:01 pm

well, it is not standard Fortran, because :

pString => aString(N)

is only allowed if pString and aString have the same LEN (and they have
not except for N=...)

Joost

Brooks Moses

2006-03-25, 7:01 pm

Gary L. Scott wrote:
> Gary L. Scott wrote:
>
> Here is a tentative solution. It is VERY scary. Since I need access to
> the storage in the main, this works. The scary part is that I can
> access beyond the allocated size because string length intrinsics are
> unaware. I must be careful to pass an explicit length or substring.
> Given the requirement to access the storage in the program main, what
> other solution is there?


Another solution might be to write a wrapper that uses an automatic
string to get the data and then copies it into something like an
ISO_VARYING_STRING representation (which is, underneath, essentially the
allocatable array of characters that you were looking for, but with all
the tricky bits already done for you), and passes the latter back to main.

- Brooks


--
The "bmoses-nospam" address is valid; no unmunging needed.
Gary L. Scott

2006-03-25, 7:01 pm

Joost wrote:
> well, it is not standard Fortran, because :
>
> pString => aString(N)
>
> is only allowed if pString and aString have the same LEN (and they have
> not except for N=...)
>
> Joost
>

But that's the whole point isn't it? I don't know what the length will
be in the main but I have to declare the pointer somehow if I want to
pass it directly to those procedures called in main. I can't use an
'automatic' method in main.

This works ok with the compiler I'm using so it will likely be my near
term solution until I figure out a better way (hopefully one that works
with the string length intrinsics and one that doesn't involve hiding
the third party API behind a bunch of new wrappers). Once I decide how
many or few APIs are impacted, I may give in and hide it behind wrappers
with some extra length checking for safety.

--

Gary Scott
mailto:garyscott@ev1.net

Fortran Library: http://www.fortranlib.com

Support the Original G95 Project: http://www.g95.org
-OR-
Support the GNU GFortran Project: http://gcc.gnu.org/fortran/index.html

Why are there two? God only knows.


If you want to do the impossible, don't hire an expert because he knows
it can't be done.

-- Henry Ford
Gary L. Scott

2006-03-25, 7:01 pm

Brooks Moses wrote:

> Gary L. Scott wrote:
>
>
>
> Another solution might be to write a wrapper that uses an automatic
> string to get the data and then copies it into something like an
> ISO_VARYING_STRING representation (which is, underneath, essentially the
> allocatable array of characters that you were looking for,


Allocatable array of characters? I don't quite follow. I can allocate
a character(1) array using standard methods with F95. But the API
expects a scalar string.

> but with all
> the tricky bits already done for you), and passes the latter back to main.


It passes it back as a fixed length string? (I've never used the varying
string module,
but I should probably study it in relation to this problem).

>
> - Brooks
>
>



--

Gary Scott
mailto:garyscott@ev1.net

Fortran Library: http://www.fortranlib.com

Support the Original G95 Project: http://www.g95.org
-OR-
Support the GNU GFortran Project: http://gcc.gnu.org/fortran/index.html

Why are there two? God only knows.


If you want to do the impossible, don't hire an expert because he knows
it can't be done.

-- Henry Ford
Brooks Moses

2006-03-25, 10:00 pm

Gary L. Scott wrote:
> Brooks Moses wrote:
>
> Allocatable array of characters? I don't quite follow. I can allocate
> a character(1) array using standard methods with F95. But the API
> expects a scalar string.


I think I probably the issue a bit. There are two independent
pieces to my proposed solution. One of them (which has nothing to do
with ISO_VARYING_STRING) is the wrapper function that passes a scalar
string to the API, and returns a character(1) array. Here's some
Fortranlike pseudocode for that, which will hopefully explain this a lot
more clearly:

program main
character(1), allocatable, dimension(:) :: thedata

len = getStringLengthFromAPI()

allocate(thedata(len))
call wrapperFunction(thedata, len)

! Other things happen with thedata here in the main program.

contains
subroutine wrapperFunction(thedata, len)
character(1), dimension(:) :: thedata
character(len) :: internalstring

call getStringFromAPI(internalstring)

! The following line needs some cleverness added....
thedata = internalstring

end subroutine
end

Similarly, any other cases where you're calling something on thedata
that expects a scalar string can use the same sort of wrappers.

>
> It passes it back as a fixed length string? (I've never used the varying
> string module,
> but I should probably study it in relation to this problem).


The second part of what I'm suggesting is a further modification of the
above pseudocode, implementing thedata as an ISO_VARYING_STRING rather
than an array of character(1) as I've shown it.

It won't do anything magical to fix the overall problem, as far as I
know (I haven't looked at it too closely either), but it should make
things like the "thedata = internalstring" operation easier, in that you
won't have to implement your own loop over all the characters in the
string for that.

- Brooks


--
The "bmoses-nospam" address is valid; no unmunging needed.
Gary L. Scott

2006-03-25, 10:00 pm

Brooks Moses wrote:
> Gary L. Scott wrote:
>
>
>
> I think I probably the issue a bit. There are two independent
> pieces to my proposed solution. One of them (which has nothing to do
> with ISO_VARYING_STRING) is the wrapper function that passes a scalar
> string to the API, and returns a character(1) array. Here's some
> Fortranlike pseudocode for that, which will hopefully explain this a lot
> more clearly:
>
> program main
> character(1), allocatable, dimension(:) :: thedata
>
> len = getStringLengthFromAPI()
>
> allocate(thedata(len))
> call wrapperFunction(thedata, len)
>
> ! Other things happen with thedata here in the main program.
>
> contains
> subroutine wrapperFunction(thedata, len)
> character(1), dimension(:) :: thedata
> character(len) :: internalstring
>
> call getStringFromAPI(internalstring)
>
> ! The following line needs some cleverness added....
> thedata = internalstring
>
> end subroutine
> end


I like that. I was just hoping to avoid wrappers for the wrappers.
I'll work on it further next w.

>
> Similarly, any other cases where you're calling something on thedata
> that expects a scalar string can use the same sort of wrappers.
>
>
>
> The second part of what I'm suggesting is a further modification of the
> above pseudocode, implementing thedata as an ISO_VARYING_STRING rather
> than an array of character(1) as I've shown it.
>
> It won't do anything magical to fix the overall problem, as far as I
> know (I haven't looked at it too closely either), but it should make
> things like the "thedata = internalstring" operation easier, in that you
> won't have to implement your own loop over all the characters in the
> string for that.
>
> - Brooks
>
>



--

Gary Scott
mailto:garyscott@ev1.net

Fortran Library: http://www.fortranlib.com

Support the Original G95 Project: http://www.g95.org
-OR-
Support the GNU GFortran Project: http://gcc.gnu.org/fortran/index.html

Why are there two? God only knows.


If you want to do the impossible, don't hire an expert because he knows
it can't be done.

-- Henry Ford
gary.l.scott@lmco.com

2006-03-27, 7:02 pm

Interesting that Salford doesn't like this in one respect because
aString does not have a "target" attribute and won't allow assignment
of both pointer and target attributes to aString.

gary.l.scott@lmco.com

2006-03-28, 7:02 pm

It works with Lahey LF95 and Absoft if you reduce the pointer
declaration to a smaller size, I assume based upon actual physical
memory (268435455) available.

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com