Home > Archive > Fortran > August 2005 > write checks challenge
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 |
write checks challenge
|
|
| David Frank 2005-08-10, 5:06 pm |
| Email received from a C++ programmer challenges me to write a function that
converts a number to english.
In responding to this challenge I propose to limit any solution to
american-english suitable for writing a check.
Below is a skeleton string function to further explain the challenge.
It is certain that below is not the fastest solution technique which is the
#1 goal.
And no, I dont have a solution but below provides some reference info.
http://www.absoluteastronomy.com/en..._in_English.htm
! ---------------------------
function write_check(dollars) result(check)
real(8) :: dollars
integer :: cents
character(100) :: check
cents = dollars*100
select case (cents)
case (:99)
write (check,'(f0.2,a)') dollars, ' < $1.00, check not authorized'
case (100:9999)
check = 'ninety-nine dollars and 99 cents'
case (10000:99999)
check = 'nine hundred ninety-nine dollars and 99 cents'
case (100000:9999999)
check = 'ninety-nine thousand nine hundred ninety-nine dollars and 99
cents'
case (10000000:99999999)
check = 'nine hundred ninety-nine thousand nine hundred ninety-nine
dollars and 99 cents'
case (100000000:)
write (check,'(f0.2,a)') dollars, ' > $999,999.99, check not authorized'
end select
end function write_check
| |
| Dick Russell 2005-08-10, 5:06 pm |
| I'm sure the challenge will produce multiple inventive solutions here.
My first thought would be to WRITE the value to a character string, to
2 places, and with a field width long enough to cover the maximum value
allowed (<billions?), then READ the individual digits plus cents from
the string with a format string like (9I1,1X,A2). Then, with a DO loop,
look first at the millions, then the thousands, then the last three
digits. Within each group, for each of the three digits in the group
(left to right) that is nonzero, concatenate the appropriate string
representing the digit value, trimmed of all but one blank, to the
composite string being assembled. For the first and third digits in the
group, this would be 'One', 'Two ', etc. For the second digit of the
group, it would be 'Twenty', 'Thirty', etc. The exception would be when
the second digit is 1; in this case, the string added would be 'Ten',
Eleven', etc., depending on what the third digit is, and the second and
third digits are thus covered with one string. At the end of handling
the first digit of the group, if it was nonzero, the string 'Hundred'
would be added to the composite. At the end of handling all three
digits of the group, if any were nonzero add the string that represents
the group ('Million', 'Thousand'). After the last group of digits has
been handled, add "and ' (or '& '), the two-character string
representing the cents, and '/100'.
Basically it's some string initializations, two DO loops, and a few
conditional IF..THENs.
Now, there could be some better algorithms, and I imagine that such is
used in automated check-writing systems. I just wrote a description of
the mental procedure I go through when converting a number to written
words for a check. I'll be interesting to see what others come up with.
| |
|
| David Frank wrote:
>
> Email received from a C++ programmer challenges me to write a function that
> converts a number to english.
> In responding to this challenge I propose to limit any solution to
> american-english suitable for writing a check.
Sorry, it's been recycled as a homework back in the dark ages (Fortran
on HP3000 I think?)... send your C++ buddy to the "Language Challenge"
on http://sdynamix.com - you'll quickly notice how C plus plusers*
flunked when they had a chance to strut their stuff.
--
* Here's a quip from one of their smartass participants: "If the winner
gets CVF compiler I'd hate to see what the looser gets" (sic).
| |
| Rich Townsend 2005-08-10, 5:06 pm |
| bvoh wrote:
> David Frank wrote:
>
>
>
> Sorry, it's been recycled as a homework back in the dark ages (Fortran
> on HP3000 I think?)... send your C++ buddy to the "Language Challenge"
> on http://sdynamix.com - you'll quickly notice how C plus plusers*
> flunked when they had a chance to strut their stuff.
The closing date for that competition was April 14th 2000. Here, borrow
my handkerchief...
| |
| e p chandler 2005-08-11, 4:01 am |
|
Dick Russell wrote:
> I'm sure the challenge will produce multiple inventive solutions here.
> My first thought would be to WRITE the value to a character string, to
> 2 places, and with a field width long enough to cover the maximum value
> allowed (<billions?), then READ the individual digits plus cents from
> the string with a format string like (9I1,1X,A2). Then, with a DO loop,
> look first at the millions, then the thousands, then the last three
> digits. Within each group, for each of the three digits in the group
> (left to right) that is nonzero, concatenate the appropriate string
> representing the digit value, trimmed of all but one blank, to the
> composite string being assembled. For the first and third digits in the
> group, this would be 'One', 'Two ', etc. For the second digit of the
> group, it would be 'Twenty', 'Thirty', etc. The exception would be when
> the second digit is 1; in this case, the string added would be 'Ten',
> Eleven', etc., depending on what the third digit is, and the second and
> third digits are thus covered with one string. At the end of handling
> the first digit of the group, if it was nonzero, the string 'Hundred'
> would be added to the composite. At the end of handling all three
> digits of the group, if any were nonzero add the string that represents
> the group ('Million', 'Thousand'). After the last group of digits has
> been handled, add "and ' (or '& '), the two-character string
> representing the cents, and '/100'.
>
> Basically it's some string initializations, two DO loops, and a few
> conditional IF..THENs.
>
> Now, there could be some better algorithms, and I imagine that such is
> used in automated check-writing systems. I just wrote a description of
> the mental procedure I go through when converting a number to written
> words for a check. I'll be interesting to see what others come up with.
One additional thing to keep in mind is that it is common to write
amounts in the thousands as multiples of 100, for example $2535 as
"twenty-five hundred thirty-five".
Also note that in case of a discrepancy between the numeric amount and
the written amount, the written amount wins. (In the banks I'm familiar
with, in the USA, etc., etc.)
| |
| Dick Russell 2005-08-11, 9:03 am |
| While $2535 could indeed be written as "twenty five hundred thirty
five," without causing ambiguity, an algorithm to automate the writing
would not have to follow this, as long as what is written is completely
unambiguous, for the reason you note. Actually, if I were writing the
check, I would write "Two Thousand Five Hundred Thirty Five..."
Now, if you were to write an algorithm that parsed the written form
back into a value, all sorts of weird things would have to be
considered for the sake of completeness. I do wonder if
check-processing procedures take a crack at deciphering written amounts
(words and numbers) and compare resulting values for consistency.
Perhaps someone from the banking industry could comment.
| |
| Gordon Sande 2005-08-11, 9:03 am |
|
e p chandler wrote:
>
> One additional thing to keep in mind is that it is common to write
> amounts in the thousands as multiples of 100, for example $2535 as
> "twenty-five hundred thirty-five".
>
> Also note that in case of a discrepancy between the numeric amount and
> the written amount, the written amount wins. (In the banks I'm familiar
> with, in the USA, etc., etc.)
>
I recently had an insert from my bank which had a label of "Courtesy"
on the numeric field to drive home the point that the only thing that
matters in a dispute is the written amount.
| |
| David Frank 2005-08-12, 9:01 am |
| ! here is a limited edition demo program, let me know if problems exist
! -----------------------
program write_checks ! $0.01 to $10000.00
real(8) :: amount
integer :: dollars, cents
do
write (*,'(a\)') 'input amount xxxx.xx >>'
read (*,'(f12.0)') amount
if (amount == 0) stop ! hit <RET> exits
dollars = amount ; cents = (amount+.001 - dollars)*100
write (*,91) '$',dollars,cents,' = ', trim(write_check(dollars,cents))
end do
91 format (a,i0,'.',i2.2,3x,2a)
stop
contains
! ---------------------------------
function write_check(dollars,cents) result(check)
implicit none
integer :: dollars, cents
integer :: n, nhuns, nths, d99, d999, d9999
character(100) :: check
character(20) :: n99(0:99) = ['
','one','two','three','four','five','six
','seven','eight','nine', &
'ten','eleven','twelve','thirteen','four
teen','fifteen','sixteen','seventeen','e
ighteen','nineteen',
&
'twenty','twenty-one','twenty-two','twenty-three','twenty-four','twenty-five','twenty-six','twenty-seven','twenty-eight','twenty-nine',
&
'thirty','thirty-one','thirty-two','thirty-three','thirty-four','thirty-five','thirty-six','thirty-seven','thirty-eight','thirty-nine',
&
'forty','forty-one','forty-two','forty-three','forty-four','forty-five','forty-six','forty-seven','forty-eight','forty-nine',
&
'fifty','fifty-one','fifty-two','fifty-three','fifty-four','fifty-five','fifty-six','fifty-seven','fifty-eight','fifty-nine',
&
'sixty','sixty-one','sixty-two','sixty-three','sixty-four','sixty-five','sixty-six','sixty-seven','sixty-eight','sixty-nine',
&
'seventy','seventy-one','seventy-two','seventy-three','seventy-four','seventy-five','seventy-six','seventy-seven','seventy-eight','seventy-nine',
&
'eighty','eighty-one','eighty-two','eighty-three','eighty-four','eighty-five','eighty-six','eighty-seven','eighty-eight','eighty-nine',
&
'ninety','ninety-one','ninety-two','ninety-three','ninety-four','ninety-five','ninety-six','ninety-seven','ninety-eight','ninety-nine']
if (dollars > 10000) then
check = 'INVALID AMOUNT' ; return
else if (dollars == 10000.and.cents == 0) then ! max authorized
check = 'ten thousand dollars and 00 cents' ; return
end if
select case (dollars)
case (0)
check = 'zero'
case (1:99)
check = n99(dollars)
case (100:999)
check = trim(n99(dollars/100)) // ' hundred'
d99 = dollars - dollars/100*100
if (d99 > 0) check = trim(check) // ' ' // trim(n99(d99))
case (1000:9999)
nths = dollars/1000 ; d999 = dollars - nths*1000
nhuns = dollars/100 ; d99 = dollars - nhuns*100
if (d999 == 0) then
check = trim(n99(nths)) // ' thousand'
else
if (d999 == d99) then ! e.g. 5099
check = trim(n99(nths)) // ' thousand ' // trim(n99(d99))
else if (nhuns > 0) then
check = trim(n99(nhuns)) // ' hundred ' // trim(n99(d99))
end if
end if
case default
check = 'WRITE CHECK ERROR...' ; return
end select
if (dollars == 1) then
write (check,91) trim(check),' dollar and ',cents,' cents'
else
write (check,91) trim(check),' dollars and ',cents,' cents'
end if
91 format (2a,i2.2,a)
end function write_check
end program write_checks
| |
| David Frank 2005-08-12, 9:01 am |
| ! Previous has many line breaks, below uses my strings.f90 module
include "strings.f90" !
http://home.earthlink.net/~dave_gemini/strings.f90
! -----------------------
program write_checks ! $0.01 to $10000.00
use string_functions
real(8) :: amount
integer :: dollars, cents
do
write (*,'(a\)') 'input amount xxxx.xx >>'
read (*,'(f12.0)') amount
if (amount == 0) stop ! hit <RET> exits
dollars = amount ; cents = (amount+.001 - dollars)*100
write (*,91) '$',dollars,cents,' = ', trim(write_check(dollars,cents))
end do
91 format (a,i0,'.',i2.2,3x,2a)
end program
| |
|
| Problem here is that initialization like this is non-standard. F95.
All expressions must have the same length.
So I had to modify the declaration to
CHARACTER(LEN=13), DIMENSION(0:99) :: n99 = (/ ' '. 'one
' &
& , 'seventy-seven', etc.
! [JvO]
| |
| David Frank 2005-08-13, 9:01 am |
|
"[JvO]" <jvo_36@hotmail.com> wrote in message
news:1123881119.954165.116890@g44g2000cwa.googlegroups.com...
> Problem here is that initialization like this is non-standard. F95.
> All expressions must have the same length.
> So I had to modify the declaration to
>
> CHARACTER(LEN=13), DIMENSION(0:99) :: n99 = (/ ' '. 'one
> ' &
> & , 'seventy-seven', etc.
>
> ! [JvO]
>
How else will the readership know that there is a better way and pressure
vendors for this easy to implement feature that makes life a lot easier for
us.
I have extended my function to handle amounts to $1 million via a much
shorter technique.
Like I originally posted, select case isnt the way to approach this
problem..
INCLUDE 'STRINGS.F90' !
http://home.earthlink.net/~dave_gemini/strings.f90
! -----------------------
PROGRAM Write_Checks ! 1 cent to $1 million
USE String_Functions
REAL(8) :: amount
INTEGER :: dollars, cents
DO
WRITE (*,'(a\)') 'input amount xxxx.xx >>'
READ (*,'(f12.0)') amount
IF (amount == 0) STOP ! <ret> exits
dollars = amount
cents = (amount+.001 - dollars)*100
WRITE (*,91) '$',dollars,cents,' = ', TRIM(Write_Check(dollars,cents))
END DO
91 FORMAT (A,I0,'.',I2.2,3X,2A)
END PROGRAM
| |
| David Frank 2005-08-13, 9:01 am |
|
"David Frank" <dave_frank@hotmail.com> wrote in message
news:_tlLe.7376$ns.2983@newsread1.news.atl.earthlink.net...
>
> "[JvO]" <jvo_36@hotmail.com> wrote in message
> news:1123881119.954165.116890@g44g2000cwa.googlegroups.com...
>
> How else will the readership know that there is a better way and pressure
> vendors for this easy to implement feature that makes life a lot easier
> for us.
>
The original release of CVF (DVF 5.0) would not accept equal lengths
either but soon after I
complained to Steve Lionel that MS Fortran did, and they were claiming
compatibility with it, they
made this SIMPLE compile adjustment..
Why the standards committee wont extend string initialization rules is
beyond me,
except of course Microsoft (first?) allowed it.
| |
| Walt Brainerd 2005-08-13, 5:01 pm |
| David Frank wrote:
> "David Frank" <dave_frank@hotmail.com> wrote in message
> news:_tlLe.7376$ns.2983@newsread1.news.atl.earthlink.net...
>
>
>
> The original release of CVF (DVF 5.0) would not accept equal lengths
> either but soon after I
> complained to Steve Lionel that MS Fortran did, and they were claiming
> compatibility with it, they
> made this SIMPLE compile adjustment..
>
> Why the standards committee wont extend string initialization rules is
> beyond me,
> except of course Microsoft (first?) allowed it.
>
>
If you read section 4.7 of the standard, you will find that,
in response to polite constructive comments like yours, the
standards committee already has done this.
Of course, when creating a standard, it is a good idea to
think a bit about making a generally useful feature, not just
hack something in that works in some places (initialization)
and not others.
--
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
| |
| David Frank 2005-08-13, 5:01 pm |
|
"Walt Brainerd" <walt@fortran.com> wrote in message
news:42FE06FB.8030708@fortran.com...
> If you read section 4.7 of the standard, you will find that,
> in response to polite constructive comments like yours, the
> standards committee already has done this.
>
> Of course, when creating a standard, it is a good idea to
> think a bit about making a generally useful feature, not just
> hack something in that works in some places (initialization)
> and not others.
>
Great, perhaps Jvo would be better served to address his complaint to his
compiler vendor for not meeting THE STANDARD in this regard.
| |
| David Frank 2005-08-13, 5:01 pm |
|
"Walt Brainerd" <walt@fortran.com> wrote in message
news:42FE06FB.8030708@fortran.com...
standards committee already has done this.
>
> Of course, when creating a standard, it is a good idea to
> think a bit about making a generally useful feature, not just
> hack something in that works in some places (initialization)
> and not others.
>
CVF allows unequal lengths in non-initialization code.
s(4:5) = ['the quick', 'brown fox jumps']
| |
| Walt Brainerd 2005-08-13, 5:01 pm |
| David Frank wrote:
> "Walt Brainerd" <walt@fortran.com> wrote in message
> news:42FE06FB.8030708@fortran.com...
> standards committee already has done this.
>
>
>
> CVF allows unequal lengths in non-initialization code.
>
> s(4:5) = ['the quick', 'brown fox jumps']
>
>
That's good. The "problem" is determining the length
and it appears (just by trial) that CVF uses the
longest entry as the length. The standard does it
differently (you give the length explicitly unless
they are all the same). Maybe somebody who was there
can tell us why j3 did it that way--I think there
are cases where it would be better to give the
length and not rely on the values to determine it
(and vice versa).
--
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
| |
| David Frank 2005-08-13, 5:01 pm |
|
"Walt Brainerd" <walt@fortran.com> wrote in message
news:42FE379B.4040502@fortran.com...
> David Frank wrote:
>
> That's good. The "problem" is determining the length
> and it appears (just by trial) that CVF uses the
> longest entry as the length.
In fixed length string assignments, CVF blank pads shorter lengths,
truncates longer lengths.
If its a initialization assignment it will warn if string is longer than
allocated length
>The standard does it
> differently (you give the length explicitly unless
> they are all the same). Maybe somebody who was there
> can tell us why j3 did it that way--I think there
> are cases where it would be better to give the
> length and not rely on the values to determine it
> (and vice versa).
>
>
Is below legal, if so what does it output:.
character(:),allocatable :: s(:)
s = ['the','quick','brown','fox']
write (*,*) (len(s(i)) , i =1,size(s))
| |
| Walter Spector 2005-08-13, 5:01 pm |
| David Frank wrote:
> ... perhaps Jvo would be better served to address his complaint to his
> compiler vendor for not meeting THE STANDARD in this regard.
"The nice thing about Standards is that there are so many to choose from".
:)
Walt Spector
(w6ws att earthlinkk dott nett)
| |
| Richard Maine 2005-08-13, 5:01 pm |
| In article <42FE379B.4040502@fortran.com>,
Walt Brainerd <walt@fortran.com> wrote:
[about why the f2003 standard requires string length to be specified
explicitly in constructors with mixed-length strings]
> Maybe somebody who was there
> can tell us why j3 did it that way--I think there
> are cases where it would be better to give the
> length and not rely on the values to determine it
> (and vice versa).
I don't recall all the details, and frankly it is not worth my
time to try to educate Dave on such things, because the education
doesn't "stick". (One could probably find the reason by searching
for past instances of Dave being told. I think you'll find multiple
cases. Indeed I think you'll find multiple cases of me explaining
it to him. I've put in far more time than I "owe" him already. Anyone
gets some for "free", but Dave used up his credit.) In very rough
outline...
1. There are hideously messy cases. No I don't recall all the
details and am not going to bother to reconstruct them yet again.
I recall Henry Zongaro as being deviously good at coming up with
examples that blew every attempt at a general scheme out of the
water. Throw in a few function calls and other tricks that make
lengths run-time variable. You can almost force the compiler to evaluate
everything twice - one pass through to find lengths, and then another
pass to get the data. That's two passes at run-time. There might
even have been worse results like indeterminacy. I just recall this
as something that seemed trivial, but got worse the more closely
you looked. People spent a *LOT* of time on this one, partly because
I think almost everyone on the committee agreed that it would be
much nicer if we didn't have to have the explicit length specification.
Of course, "certain people" claim that the committee was just being
capricious (if one is going to be capricious, best not spend so much
time in doing so).... or that the only cases they care about seem
ok and the others don't matter.
2. The f2003 syntax extends cleanly to all types, including the other
intrinsic types and derived types. If you special-case it to string
lengths, then it doesn't extend well and you end up with a wart. Likely
as not, you later find that you also need the general case and thus end
up with two syntaxes - the general one and the string one.
| |
| David Frank 2005-08-13, 10:00 pm |
|
"Walter Spector" <w6ws_xthisoutx@earthlink.net> wrote in message
news:42FE5F07.786981CD@earthlink.net...
> David Frank wrote:
>
> "The nice thing about Standards is that there are so many to choose from".
>
> :)
>
> Walt Spector
> (w6ws att earthlinkk dott nett)
AFAIK there is only one that can be labeled as THE STANDARD,
ALL previous can not claim that distinction.
| |
| Walt Brainerd 2005-08-13, 10:00 pm |
| David Frank wrote:
> "Walt Brainerd" <walt@fortran.com> wrote in message
> news:42FE379B.4040502@fortran.com...
>
>
>
> In fixed length string assignments, CVF blank pads shorter lengths,
> truncates longer lengths.
> If its a initialization assignment it will warn if string is longer than
> allocated length
>
>
>
>
> Is below legal, if so what does it output:.
>
> character(:),allocatable :: s(:)
>
> s = ['the','quick','brown','fox']
>
> write (*,*) (len(s(i)) , i =1,size(s))
>
>
>
No, as said before, you must explicitly give
the length in the array constructor (it has
nothing to do with the declaration of s).
--
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
| |
| Rich Townsend 2005-08-13, 10:00 pm |
| David Frank wrote:
> "Walter Spector" <w6ws_xthisoutx@earthlink.net> wrote in message
> news:42FE5F07.786981CD@earthlink.net...
>
>
>
> AFAIK there is only one that can be labeled as THE STANDARD,
> ALL previous can not claim that distinction.
>
One what? Fortran has more than a single part to 'The Standard'. The
current ISO Varying String specification is also 'The Standard', as is
the Conditional Compilation specification.
cheers,
Rich
| |
| David Frank 2005-08-13, 10:00 pm |
|
"Walt Brainerd" <walt@fortran.com> wrote in message
news:42FE7B5B.2010203@fortran.com...
> David Frank wrote:
>
> No, as said before, you must explicitly give
> the length in the array constructor (it has
> nothing to do with the declaration of s).
>
I think Dick Hendrickson has posted that once a allocatable string is
allocated it accepts assignments to
a shorter or longer length, but will it accept assignment to a smaller or
larger size?
Assuming its true then having to allocate a allocatable string with a
nominal len,size is DUMB!
character(:),allocatable :: s(:)
allocate ( character(1) :: s(1) ) ! nominal len,size
s = ['quick','brown,'fox','jumps']
AND, my question left hanging from your response is, can there be "jagged
arrays"
(string arrays whose elements have varying lens)
| |
| Rich Townsend 2005-08-13, 10:00 pm |
| David Frank wrote:
> "Walt Brainerd" <walt@fortran.com> wrote in message
> news:42FE7B5B.2010203@fortran.com...
>
>
>
> I think Dick Hendrickson has posted that once a allocatable string is
> allocated it accepts assignments to
> a shorter or longer length, but will it accept assignment to a smaller or
> larger size?
>
> Assuming its true then having to allocate a allocatable string with a
> nominal len,size is DUMB!
>
> character(:),allocatable :: s(:)
> allocate ( character(1) :: s(1) ) ! nominal len,size
>
> s = ['quick','brown,'fox','jumps']
>
> AND, my question left hanging from your response is, can there be "jagged
> arrays"
> (string arrays whose elements have varying lens)
Yep, use an array of ISO_VARYING_STRING datatypes.
cheers,
Rich
| |
| David Frank 2005-08-14, 9:00 am |
|
"Dick Russell" <richard.russell@shawgrp.com> wrote in message
news:1123762351.867982.174480@g49g2000cwa.googlegroups.com...
> While $2535 could indeed be written as "twenty five hundred thirty
> five," without causing ambiguity, an algorithm to automate the writing
> would not have to follow this, as long as what is written is completely
> unambiguous, for the reason you note. Actually, if I were writing the
> check, I would write "Two Thousand Five Hundred Thirty Five..."
>
My 1st crack at this did write "twenty-five hundred thirty-five"
however my 2nd (and final?) solution:
http://home.earthlink.net/~dave_gemini/strings.f90
does not.
> Now, if you were to write an algorithm that parsed the written form
> back into a value, all sorts of weird things would have to be
> considered for the sake of completeness. I do wonder if
> check-processing procedures take a crack at deciphering written amounts
> (words and numbers) and compare resulting values for consistency.
> Perhaps someone from the banking industry could comment.
>
I see it as about same degree of difficulty, but I'm probably wrong.
| |
| Walt Brainerd 2005-08-14, 5:01 pm |
| David Frank wrote:
> "Walt Brainerd" <walt@fortran.com> wrote in message
> news:42FE7B5B.2010203@fortran.com...
>
>
>
> I think Dick Hendrickson has posted that once a allocatable string is
> allocated it accepts assignments to
> a shorter or longer length, but will it accept assignment to a smaller or
> larger size?
>
> Assuming its true then having to allocate a allocatable string with a
> nominal len,size is DUMB!
>
> character(:),allocatable :: s(:)
> allocate ( character(1) :: s(1) ) ! nominal len,size
>
> s = ['quick','brown,'fox','jumps']
>
> AND, my question left hanging from your response is, can there be "jagged
> arrays"
> (string arrays whose elements have varying lens)
Just so nobody else is by Dave's diversions,
to summarize once more:
The syntax [ "a", "bc" ] is an illegal array constructor
(in Part 1 of the Fortran 03 standard).
This has nothing to do with "jagged arrays" or allocatable
arrays or anything else.
You can write [ character(len=7) :: "a", "bc" ]
The value of this constructor is a one-dimensional
two-element array of character strings of length 7.
I won't try again on this topic. I leave for Alaska
in a couple of hours.
--
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
| |
| Clive Page 2005-08-15, 5:02 pm |
| In message <1123881119.954165.116890@g44g2000cwa.googlegroups.com>,
"[JvO]" <jvo_36@hotmail.com> writes
>Problem here is that initialization like this is non-standard. F95.
>All expressions must have the same length.
>So I had to modify the declaration to
>
>CHARACTER(LEN=13), DIMENSION(0:99) :: n99 = (/ ' '. 'one
> ' &
>& , 'seventy-seven', etc.
True. But if you use a DATA statement to do the initialisation, you
don't need all the string constants to have the same length.
--
Clive Page
| |
|
|
David Frank schreef:
> "Walt Brainerd" <walt@fortran.com> wrote in message
> news:42FE06FB.8030708@fortran.com...
>
I agree with Walt.
[color=darkred]
> Great, perhaps Jvo would be better served to address his complaint to his
> compiler vendor for not meeting THE STANDARD in this regard.
No, it's on purpose that I [try to] write Standard conforming Fortran.
And until I have an F03 compiler , I don't use [] or any other of the
new features of Fortran.
Jan van Oosterwijk , aka [JvO]
| |
| Dick Hendrickson 2005-08-16, 5:06 pm |
|
David Frank wrote:
> "Walt Brainerd" <walt@fortran.com> wrote in message
> news:42FE7B5B.2010203@fortran.com...
>
>
>
> I think Dick Hendrickson has posted that once a allocatable string is
> allocated it accepts assignments to
> a shorter or longer length, but will it accept assignment to a smaller or
> larger size?
Yes, the rule is in section 7.4.1.3 of THE STANDARD. It's a
two part rule to cover all of the cases.
1) If the left hand variable is allocated and the right and
variable differ in array shape (but can't differ in rank)
or any length parameter (like character length) then the
variable is deallocated.
2) If the variable is not allocated (perhaps because of rule
1), it is allocated with the right shape and lengths.
So, you can make them longer or shorter as you need.
>
> Assuming its true then having to allocate a allocatable string with a
> nominal len,size is DUMB!
>
> character(:),allocatable :: s(:)
> allocate ( character(1) :: s(1) ) ! nominal len,size
>
> s = ['quick','brown,'fox','jumps']
Your syntax here is incorrect, each element in an
array constructor must have the same length or you
must force the length with a declaration in the constructor.
Something like
s = [character(len=5)::'quick','brown,'fox',
'jumps']
will do the right thing.
The reason for requiring the length declaration is to
cover cases like
[ ( 'a', i = 1,n), ('bb', i = i,m) ...]
where it's not obvious what to do if any of the n, m, ...
are zero, or
[ (character_func(f(i)), i = g(), h() ) ]
where it's less than not obvious what to do if
g, h, or f do sufficiently interesting things.
Incidently, rule 2) says you don't need to preallocate s
before the assignment.
>
> AND, my question left hanging from your response is, can there be "jagged
> arrays"
> (string arrays whose elements have varying lens)
No, all arrays in Fortran are "rectangular" and all elements
of a character array have the same size. As someone (Rich I
think) said, you can have a (rectangular) array of
structures and each element can have different sized
internal parts.
Sorry if I'm repeating what others have said, I just got
back from vacation and am a little behind and out of order.
Dick Hendrickson
>
>
>
>
|
|
|
|
|