For Programmers: Free Programming Magazines  


Home > Archive > Fortran > April 2005 > Little question about FORTRAN programming









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 Little question about FORTRAN programming
beatdown

2005-04-06, 12:21 pm

Hi all,

I would like someone to help me with this problem. I have the following
lines in a FORTRAN program:

....
character*18 hosts(30)
integer i,tid(30)
....
3 format(A18,3X,A18,3X,A18)
31 format(I18,3X,A18,3X,I18)
....
print 3,'Llamada','Host','TID'
print 31,i,hosts(i),tid(i)
....
end

Note: 'LLamada' simply means 'call' in my home language (Spanish)

Well, when I run my program I get something like this:

Llamada Host TID
1 GnomeInTheShell 262206

As you can see, when using the 31 label format it shows a right-aligned
integer (i) in a 'cell' of 18 spaces, 3 blank spaces, a left-alligned
string (hosts(i)) in a 'cell' of 18 spaces, ...
What can I do to show the string right-alligned too? I think the
problem is because I am merging integers and characters in a format
specification, because the fomat specification with label 3 (which
contains only characters) works fine...

Thanks.

Brooks Moses

2005-04-06, 12:21 pm

beatdown wrote:
> character*18 hosts(30)
> integer i,tid(30)
> ...
> 3 format(A18,3X,A18,3X,A18)
> 31 format(I18,3X,A18,3X,I18)
> ...
> print 3,'Llamada','Host','TID'
> print 31,i,hosts(i),tid(i)

[...]
> Llamada Host TID
> 1 GnomeInTheShell 262206
>
> As you can see, when using the 31 label format it shows a right-aligned
> integer (i) in a 'cell' of 18 spaces, 3 blank spaces, a left-alligned
> string (hosts(i)) in a 'cell' of 18 spaces, ...
> What can I do to show the string right-alligned too? I think the
> problem is because I am merging integers and characters in a format
> specification, because the fomat specification with label 3 (which
> contains only characters) works fine...


No, that's not the problem. Your hosts(i) string _is_ right-aligned.
However, the string -- because it's declared as character*18 -- is 18
characters long, and the last three of those 18 characters are blanks,
and those blanks are considered as part of the string when aligning it.

I suspect that if you replace hosts(i) with trim(hosts(i)), and thereby
remove the trailing blanks from the string, you'll get the results that
you want.

- Brooks


--
The "bmoses-nospam" address is valid; no unmunging needed.
glen herrmannsfeldt

2005-04-06, 12:21 pm

beatdown wrote:


> I would like someone to help me with this problem. I have the following
> lines in a FORTRAN program:


> character*18 hosts(30)
> integer i,tid(30)


> 3 format(A18,3X,A18,3X,A18)
> 31 format(I18,3X,A18,3X,I18)
> print 3,'Llamada','Host','TID'
> print 31,i,hosts(i),tid(i)


> Well, when I run my program I get something like this:


> Llamada Host TID
> 1 GnomeInTheShell 262206


> As you can see, when using the 31 label format it shows a right-aligned
> integer (i) in a 'cell' of 18 spaces, 3 blank spaces, a left-alligned
> string (hosts(i)) in a 'cell' of 18 spaces, ...
> What can I do to show the string right-alligned too? I think the
> problem is because I am merging integers and characters in a format
> specification, because the fomat specification with label 3 (which
> contains only characters) works fine...


It doesn't have anything to do with merging I and A format. It has only
to do with the format descriptor and format item. If the string is
shorter than the specified width. 'Llamada' and 'Host' are shorter than
18, they are blank padded on the left. hosts(i) and tid(i) have length
18, with blanks already included in the value, and so are printed.

If you apply TRIM I believe that removes the blanks and the string
length will then allow right justifying by A format.

-- glen

beatdown

2005-04-06, 12:21 pm

Ok,thank you. Now I understand what is the problem, but I cannot fix it
with TRIM. I am using Fortran 77 and I think TRIM is available only
since Fortran 90. Am I right? So what can I do to use TRIM? Sorry, I am
new into Fortran.

Thank you again.

beliavsky@aol.com

2005-04-06, 12:21 pm

beatdown wrote:
> Ok,thank you. Now I understand what is the problem, but I cannot fix

it
> with TRIM. I am using Fortran 77 and I think TRIM is available only
> since Fortran 90. Am I right? So what can I do to use TRIM? Sorry, I

am
> new into Fortran.


Why not use g95 http://www.g95.org, a free Fortran 95 compiler, or
gfortran http://www.gfortran.org , a compiler with most but not all of
F95 implemented?

I think Fortran 77 has the len_trim and the ':' character substring
operator, as illustrated by the following code

integer nlen
character (len=5) word
word = 'dog '
nlen = len_trim(word)
print*,"'" // word(1:nlen) // "'"
end

which works with the g77 Fortran compiler and produces output

'dog'

Richard E Maine

2005-04-06, 12:21 pm

In article <1112626843.990653.173030@l41g2000cwc.googlegroups.com>,
beliavsky@aol.com wrote:

> I think Fortran 77 has the len_trim


Not in the f77 standard. However, it is simple to write len_trim() as
user code in standard f77 (see caveats and exceptions below). Trim() is
a different matter - it can't be written in standard f77 (or if possible
at all, it is really tricky).

Arcane exceptions: User procedures in f77 can't be pure, elemental, or
generic, so you can't quite emulate everything about the f90 len_trim,
but those aspects usually aren't cared about in this kind of application
anyway (and the concepts of pure and elemental aren't even in f77 at
all). Note that the elementalness is probably the single biggest reason
for the existence of len_trim() in f90; trim() can't be elemental, so if
you want something related but elemental, len_trim() is what you can get.

Subtle, but not so arcane caveat: Zero-length substrings are not allowed
in standard f77 (and have been known to cause strange symptoms in some
compilers). The f90 len_trim can return zero as a result; that's even a
reasonably common case and is not a problem at all in f90. If you want
to use the result of a len_trim to define a substring in f77, then you
need special consideration for the zero-length case.

You could make an f77 len_trim return 1 for blank strings; that's not
entirely consistent with its meaning, but then the f77 treatment of
zero-length strings is not entirely consistent. You could special-case
what you do with a return value of zero, but that would require storing
the return value in a temporary variable instead of using len_trim()
directly in an expression. Or you could just make sure that blank
strings are ruled out beforehand.

The other option, of course, is to just close your eyes and hope that it
will happen to work anyway in the compilers of interest to you, but I
advise against that one :-(

--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain | experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
Walt Brainerd

2005-04-06, 12:21 pm

Richard E Maine wrote:
> In article <1112626843.990653.173030@l41g2000cwc.googlegroups.com>,
> beliavsky@aol.com wrote:
>
>
>
>
> Not in the f77 standard. However, it is simple to write len_trim() as
> user code in standard f77 (see caveats and exceptions below). Trim() is
> a different matter - it can't be written in standard f77 (or if possible
> at all, it is really tricky).


But you can easily print the trim of a string
once you get len_trim written (which, as you say,
is easy, for the common case). This seems to
work with f77. Odd cases (eg all blanks not
considered).

function lentrm(s)
character*(*) s
do lentrm = len(s),1,-1
if (s(lentrm:lentrm) .ne. ' ') return
end do
end

program p
character*12 s
external lentrm
s="xxx"
print *, "a"//s(1:lentrm(s))//"z"
end

--
Walt Brainerd +1-877-355-6640 (voice & fax)
The Fortran Company +1-520-760-1397 (outside USA)
6025 N. Wilmot Road walt@fortran.com
Tucson, AZ 85750 USA http://www.fortran.com
Walt Brainerd

2005-04-06, 12:21 pm

Richard E Maine wrote:
> In article <1112626843.990653.173030@l41g2000cwc.googlegroups.com>,
> beliavsky@aol.com wrote:
>
>
>
>
> Not in the f77 standard. However, it is simple to write len_trim() as
> user code in standard f77 (see caveats and exceptions below). Trim() is
> a different matter - it can't be written in standard f77 (or if possible
> at all, it is really tricky).


But you can easily print the trim of a string
once you get len_trim written (which, as you say,
is easy, for the common case). This seems to
work with f77. Odd cases (eg all blanks not
considered).

function lentrm(s)
character*(*) s
do lentrm = len(s),1,-1
if (s(lentrm:lentrm) .ne. ' ') return
end do
end

program p
character*12 s
external lentrm
s="xxx"
print *, "a"//s(1:lentrm(s))//"z"
end

--
Walt Brainerd +1-877-355-6640 (voice & fax)
The Fortran Company +1-520-760-1397 (outside USA)
6025 N. Wilmot Road walt@fortran.com
Tucson, AZ 85750 USA http://www.fortran.com
Walt Brainerd

2005-04-06, 12:21 pm

Richard E Maine wrote:
> In article <1112626843.990653.173030@l41g2000cwc.googlegroups.com>,
> beliavsky@aol.com wrote:
>
>
>
>
> Not in the f77 standard. However, it is simple to write len_trim() as
> user code in standard f77 (see caveats and exceptions below). Trim() is
> a different matter - it can't be written in standard f77 (or if possible
> at all, it is really tricky).


But you can easily print the trim of a string
once you get len_trim written (which, as you say,
is easy, for the common case). This seems to
work with f77. Odd cases (eg all blanks not
considered).

function lentrm(s)
character*(*) s
do lentrm = len(s),1,-1
if (s(lentrm:lentrm) .ne. ' ') return
end do
end

program p
character*12 s
external lentrm
s="xxx"
print *, "a"//s(1:lentrm(s))//"z"
end

--
Walt Brainerd +1-877-355-6640 (voice & fax)
The Fortran Company +1-520-760-1397 (outside USA)
6025 N. Wilmot Road walt@fortran.com
Tucson, AZ 85750 USA http://www.fortran.com
Gib Bogle

2005-04-06, 12:21 pm

Richard E Maine wrote:

> The other option, of course, is to just close your eyes and hope that it
> will happen to work anyway in the compilers of interest to you, but I
> advise against that one :-(


That approach has always worked for me ;-)

Gib

------------ And now a word from our sponsor ----------------------
For a quality mail server, try SurgeMail, easy to install,
fast, efficient and reliable. Run a million users on a standard
PC running NT or Unix without running out of power, use the best!
---- See http://netwinsite.com/sponsor/sponsor_surgemail.htm ----
Brooks Moses

2005-04-06, 12:21 pm

beliavsky@aol.com wrote:
> I think Fortran 77 has the len_trim and the ':' character substring
> operator, as illustrated by the following code
>
> integer nlen
> character (len=5) word
> word = 'dog '
> nlen = len_trim(word)
> print*,"'" // word(1:nlen) // "'"
> end
>
> which works with the g77 Fortran compiler and produces output


As Richard Maine pointed out, len_trim isn't standard Fortran 77. There
is, however, this awkward little construction that I got out of an
output routine that I inherited:

print*, word(1:index(word,' ')-1)

This will trim off the _first_ space and everything after it, rather
than merely trimming trailing whitespace. If your strings don't have
whitespace in them, though, it should work fine.

- Brooks


--
The "bmoses-nospam" address is valid; no unmunging needed.
Richard E Maine

2005-04-06, 12:21 pm

In article <42524FA8.D21EA25C@cits1.stanford.edu>,
Brooks Moses <bmoses-nospam@cits1.stanford.edu> wrote:

> print*, word(1:index(word,' ')-1)
>
> This will trim off the _first_ space and everything after it, rather
> than merely trimming trailing whitespace. If your strings don't have
> whitespace in them, though, it should work fine.


Well, this does have quite a few caveats.

First, it shares the problem I mentioned about len_trim - it can result
in a substring word(1:0), which is not valid f77. I have seen f77
compilers that choke on this nonstandard substring (although I suspect
many recent ones probably accept it). It is standard in f90, but then in
f90, one would just use trim().

Second, this fails if word has no blanks. That will give a substring
word(1:-1), which will not give a "reasonable" result even if the
compiler accepts zero-length substrings. One would "obviously" want the
whole string rather than a zero-length one. I'd think that would be a
case that one would want to work. Of course, it is possible that this is
used only in a context where at least one blank is guaranteed, but it
concerns me to see it presented without mention of that requirement,
which seems like a pretty major one to me.

--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain | experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
glen herrmannsfeldt

2005-04-06, 12:21 pm

Richard E Maine wrote:

> In article <42524FA8.D21EA25C@cits1.stanford.edu>,
> Brooks Moses <bmoses-nospam@cits1.stanford.edu> wrote:


[color=darkred]
[color=darkred]
> Well, this does have quite a few caveats.


> First, it shares the problem I mentioned about len_trim - it can result
> in a substring word(1:0), which is not valid f77. I have seen f77
> compilers that choke on this nonstandard substring (although I suspect
> many recent ones probably accept it). It is standard in f90, but then in
> f90, one would just use trim().


word(1:max(1,index(word,' ')-1))

Should leave one blank in the case that word contains all blanks,
which won't be noticed right or left justified in A format.

> Second, this fails if word has no blanks. That will give a substring
> word(1:-1), which will not give a "reasonable" result even if the
> compiler accepts zero-length substrings. One would "obviously" want the
> whole string rather than a zero-length one. I'd think that would be a
> case that one would want to work. Of course, it is possible that this is
> used only in a context where at least one blank is guaranteed, but it
> concerns me to see it presented without mention of that requirement,
> which seems like a pretty major one to me.


word(1:max(1,index(word//' ',' ')-1))

maybe better than the first I came up with,

word(1:max(1,mod(index(word,' ')+18,19)))

replace 18 and 19 with len(word) and len(word)+1 to be more general.

The mod, 18, and 19 wrap zero up to 18, and subtract one
for index between 1 and 19.

-- glen

meek@skyway.usask.ca

2005-04-06, 12:21 pm

In a previous article, beliavsky@aol.com wrote:
>beatdown wrote:
>it
>am
>
>Why not use g95 http://www.g95.org, a free Fortran 95 compiler, or
>gfortran http://www.gfortran.org , a compiler with most but not all of
>F95 implemented?
>
>I think Fortran 77 has the len_trim and the ':' character substring

In Watcom Fortran 77 the function is called lentrim.
Chris
<snip>
Sponsored Links







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

Copyright 2009 codecomments.com