I want to concatenate two strings, but I don't know a priori how long
the strings will be ( the strings are the output from another program
and are respectively read in from a file and handed over by command
line.
When I want to concatenate these strings, I always get spaces in
between.
The declarations are the following :
INTEGER status, system, len1
CHARACTER*30 command
CHARACTER*30 commandline1
CHARACTER*60 whole_command
opdracht = './start '
len1 = LEN(opdracht)
PRINT *, opdracht, len1
commandline1 = '830fiber'
whole_command = opdracht // commandline1
PRINT *, whole_command
Because of the declaration "CHARACTER*30 command", the characters after
'./start ' are filled up with spaces and the concatenation is not good.
Moreover the 'LEN'-command gives '30' and not the actual size of the
string.
How can you solve this problem ?
With best regards,
Wim Van Paepegem
--
----------------------------------------
Wim Van Paepegem
Aspirant F.W.O.
University of Ghent
Mechanica van Materialen en Constructies
Sint-Pietersnieuwstraat 41
9000 Gent
Belgium
Tel: +32-09-264.42.07
Fax: +32-09-264.35.87
E-mail : Wim.Van...@rug.ac.be
----------------------------------------
--
Use intrinsic function TRIM:
whole_command = TRIM(opdracht) // commandline1
--
Helmut Mann
mann_eng...@compuserve.com
Helmut Mann wrote:
> Use intrinsic function TRIM:
>
> whole_command = TRIM(opdracht) // commandline1
>
Hello, Mr. Mann,
well, if it was that simple, I have found it myself :-).
I use the Sun Workshop f77 compiler and that compiler does not recognize
the TRIM function at all.
Regards,
Wim
A few extra points.
1. It may sound like "just picking at words", but if you don't get
the concept right, you (the original poster - I'm very sure that
Mike understands) will have continuing problems with understanding
Fortran character handling...
The 30 *IS* the actual size of the string. Period. If you declare
a string to be of length 30 then it has *EXACTLY* that length, never
any more and never any less. When you assign it with a value that
has some other length, the data is truncated or blank-padded to
the length 30. Those blanks are part of the string and are just
as ordinary a part as any other characters.
(Thus the LEN intrinsic is "uninteresting" in many cases; you use
it mostly for things like assumed length dummy arguments).
2. As Mike mentions, f90 has the TRIM intrinsic for exactly this, but
f77 doesn't.
3. You won't find it particularly easy to write TRIM as a user-written
function. In fact, I don't tthink I recall how to do it. I think
I recall seeing an example of how, but it is not *AT ALL* simple.
What is, however, easy is to write a function (like the f90 len_trim)
that returns an integer with the length of the non-blank part of the
string. Then use that length to write a substring as in
l = len_trim(opdracht)
whole_command = opdracht(:l) // commandline1
--
Richard Maine
ma...@altair.dfrc.nasa.gov
>well, if it was that simple, I have found it myself :-).
>I use the Sun Workshop f77 compiler and that compiler does not recognize
>the TRIM function at all.
See if it has len_trim or lentrim. I've seen that as an extension in
some F77 compilers for some time.
If not, then write one as Richard suggests. The method is to look for
a non-blank, starting at the back:
integer function ltrim(string,length)
character*(*) string
do 10, i = length,1,-1
if(string(i:i).ne.' ') go to 20
10 continue
20 continue
ltrim = i
return
end
The "if" will need to be more elaborate if the string could be filled
with stuff other than blanks.
Ken Plotkin
See if it has LEN_TRIM. That will give you the length of the
string minus the trailing blanks. Then you can do something like
character*60 foobar,foo,bar
foobar = foo(1:len_trim(foo))//bar(1:len_trim(bar))
Jeff
I'd like anyone who knows this technique to post it. I can't imagine
how it would work.
--
J. Giles
Well, that's the alternative Richard Maine mentioned to avoid having
to write the TRIM function. What I'm interested in is actually writing
a TRIM function (if that's possible). That is, a function returning a
character string whose length depends on the value of its arguments
(or some other run-time information). If there's really a way, as Richard
Maine suggests there might be, I'd like to see it.
It is fairly trivial to write a function that returns an integer that specifies
a substring bound which you can then apply to the original string. That's
not what Richard Maine was talking about.
--
J. Giles
By the way, I can already think of two ways to *nearly* achieve this.
One is to use the supplimentary standard for varying length strings.
This has the well known problem of causing memory leaks in most
implementations (since, when pointers go out of scope their target
is not deallocated). The other way is with a rather sophisticated
preprocessor which would generate code for the varying string
stuff *and* keep track of when things go out of scope so that
it could generate deallocations for it. Both these are outside
the Fortran 90 standard though (and certainly not possible within
any F77 implementation).
--
J. Giles
An approximation is:
PROGRAM MAIN
CHARACTER*40 TEXT
INTEGER I,TXTLEN
TEXT = 'Some text'
I=1
PRINT 10,TEXT,I
I=2
PRINT 10,TEXT(1:TXTLEN(TEXT)),I
10 FORMAT(1X,A,I1)
END
INTEGER FUNCTION TXTLEN(TEXT)
CHARACTER*(*) TEXT
C
C Calculate lenght of TXT excluding
C trailing blanks & null chars.
C
C Input:
C TEXT Text for which lenght shall be found.
C
C Result:
C Length of text excluding trailing blanks/nulls.
C
CHARACTER*1 NULL
INTEGER L,K
NULL = CHAR(0)
C
K = LEN(TEXT)
DO 100 L = K,1,-1
IF (TEXT(L:L).NE.' ' .AND. TEXT(L:L).NE.NULL) GOTO 110
100 CONTINUE
C
L = 0
110 CONTINUE
TXTLEN = L
C
RETURN
END
Intrinsic functions are special. A user cannot write a function equivalent
to TRIM in Fortran 95.
This special treatment is not new. Even in FORTRAN 77, a user could not
write a routine equivalent to MAX.
Sincerely,
Bob Corbett
That's what I would have thought. But comments from Richard Maine, even
when he refers to vaguely remembered ideas, cannot be dismissed out of hand.
--
J. Giles
On the contrary, it's possible:
FUNCTION MYTRIM(ARG)
CHARACTER(*) ARG
CHARACTER(LEN_TRIM(ARG)) MYTRIM
MYTRIM = ARG
END FUNCTION
Regards,
Jean Vezina
Interesting notion. I don't think the length of a procedure argument
is the kind of thing allowed in an initialization expression, much less a
KIND or LEN attribute specification. But it's worth investigating.
--
J. Giles
This, as written, is not permitted. The LEN_TRIM function is
not among the functions permitted in a specification expression.
However, both LEN and TRIM are permitted. So, LEN(TRIM(ARG))
should be acceptable. That appears to be the solution unless there's
some additional constraint my tired eyes can't find this time of night.
Good idea!
Now, I wonder how many implemenations actually do allow this?
--
J. Giles
LEN_TRIM *is* allowed as an specification expression (since it is
an elemental intrinsic function). So the above will actually work.
To show how silly you can get late at night after a particularly silly
dinner party, I actually wrote and posted an article suggesting the
following: Both LEN and TRIM are allowed, so, although it's possible
to write the function declared as:
CHARACTER(len(trim(arg))) NYTRIM
This is obviously just silly. It is not really a good notion to
define your own trim in terms of the built-in trim. If you read
that before the cancellation reaches your news server, you can
have a good laugh at my expense.:-)
In any case, the original question was how to do this in F77.
So, even if F90 or F95 allowed LEN_TRIM in a specification
expression, it is clearly not allowed in F77 (which doesn't even
have the LEN_TRIM intrinsic at all).
--
J. Giles
> > Intrinsic functions are special. A user cannot write a function equivalent
> > to TRIM in Fortran 95.
>
> On the contrary, it's possible:
>
> FUNCTION MYTRIM(ARG)
> CHARACTER(*) ARG
> CHARACTER(LEN_TRIM(ARG)) MYTRIM
> MYTRIM = ARG
> END FUNCTION
>
> Regards,
>
> Jean Vezina
In Fortran 77, Len_Trim is a user function, not an intrinsic. I do not think you can
use user functions in specifications. How is MYTRIM declared and called in the caller
program?
I always did this the hard way:
...caller subroutine...
...
INTEGER Len_Trim
EXTERNAL Len_Trim
...
...references using Len_Trim: a(1:Len_Trim(a))...
...
END
FUNCTION Len_Trim(a)
INTEGER Len_Trim, i
CHARACTER*(*) a
DO 10 i=1,Len(a),-1
IF (a(i:i).NE.' ') GO TO 20
10 CONTINUE
20 CONTINUE
Len_Trim=i-1
END
I couldn't write Trim() but I could get the functionality. Most of my stuff has the
above as I haven't converted them to Fortran90 yet (takes too much work.)
Yes, intrinsic functions are special - but TRIM is not one of the special
ones.
Here is a Fortran90 version:
FUNCTION mytrim(ch)
CHARACTER*(*),INTENT(IN) :: ch
CHARACTER*(LEN_TRIM(ch)) :: mytrim
mytrim = ch
END FUNCTION
This looks to me like it implements "TRIM".
Not much help to the original poster though, since he wanted F77. Oh well.
Cheers,
--
...........................Malcolm Cohen, NAG Ltd., Oxford, U.K.
(mal...@nag.co.uk)
> Robert Corbett wrote in message <800gm8$dg3$1...@engnews1.eng.sun.com>...
> ...
> >Intrinsic functions are special. A user cannot write a function equivalent
> >to TRIM in Fortran 95.
>
> That's what I would have thought. But comments from Richard Maine, even
> when he refers to vaguely remembered ideas, cannot be dismissed out of hand.
Thanks for the expression of confidence, misplaced though it may be.
Though I certainly can't get 'em right 100% of the time, perhaps I
can try to live up to the confidence by admitting when I goof; I
can't get that one 100% either, but I can come closer.
Alas, it appears that I must have been confusing two different things.
I was half expecting that someone would repost whatever it was that I
recalled; I'm sure that it was here that I saw whatever it is I'm
remembering.
But on reading the followups and then thinking further, I conclude
1. Its embarassingly trivial in f90, as illustrated by some of the
samples posted. Doesn't seem particularly useful (since if you have
f90, you have the intrinsic TRIM), but its trivial to do. That doesn't
match whatever it is I was remembering.
2. I'm now convinced that it isn't possible at all in f77 (within the
language). I can't even see an avenue that provides an oportunity
for exploitation like specification expressions do in f90.
(There, now that I said I'm convinced its impossible, that should
drag up a counterexample if there really is one).
My recollections included one posting that involved using TRANSFER to
turn a character string into an array of characters, and then using
array operations, and I think the MERGE intrinsic got in there
somewhere. Really tricky...or anyway I thought so. Must have been
for a different problem than replicating TRIM, however. I'm trying to
recall what problem it was, but its just not "coming" at the moment.
--
Richard Maine
ma...@altair.dfrc.nasa.gov
Very nice. I had not considered using LEN_TRIM in the declaration.
Sincerely,
Bob Corbett
>2. I'm now convinced that it isn't possible at all in f77 (within the
> language). I can't even see an avenue that provides an oportunity
> for exploitation like specification expressions do in f90.
I agree with you - I also think it's impossible.
>My recollections included one posting that involved using TRANSFER to
>turn a character string into an array of characters, and then using
>array operations,
Perhaps what you remember is some code I posted once, not entirely
seriously, to solve the problem of turning an integer into a
left-justified string of digits. This turns out to be quite easy in f95,
impossible in f77, but just possible in f90 if you declare the function
argument like this:
CHARACTER(LEN=12 - MAX(0,SIGN(1,intval)) - VERIFY(TRANSFER(ACHAR(48+ &
(/(MOD(MAX(1,ABS(intval))/10**n,10),n=9,0,-1)/) ), &
"1234567890"), ACHAR(48)) ) :: string
which is valid Fortran, but gave indigestion to one or two compilers.
Other people found alternative ways of doing this, conceptually simpler
but actually longer.
--
Clive Page, e-mail: cgp (at) le (dot) ac (dot) uk
Dept of Physics & Astronomy,
University of Leicester.
Yes. That was it. I recognize it, even if I couldn't duplicate it.
Not that I've actually worked through it completely to verify that it
works as advertised, but I can believe that it does. I see that it
shares with TRIM the property of returning a string with a length that
depends on the value of an argument. That's probably the connection
that was making me vaguely recall this.
--
Richard Maine
ma...@altair.dfrc.nasa.gov