This article is from the Mac Programming FAQ, by Jon Watte firstname.lastname@example.org with numerous contributions by others.
Once you've got an Str255, you want to call the routine
StringToExtended to change the number into type extended80, which is the
80-bit floating point type. The nice thing about StringToExtended is
that it even works in funky foreign language scripts like Chinese. To
use the routine, you must pass it not only the Str255 that you want
converted, but also the results of the StringToFormatRec routine and the
GetIntlResourceTable routine. The documentation is generally difficult,
so I'll describe the parameters and give you a code example below.
Here's what you pass to StringToExtended:
Obviously the string representation of the number.
This is simply the format that you expect the number to be. For
example, if you wanted a positive integer with up to 3 decimal places,
you would want the format to be "###". (The "#" symbol means a non-zero
filled digit, whereas a "0" would mean zero filled.) If you wanted an
floating point exponential notation with up to 2 digit integer portion,
exactly 2 digit decimal portion, and exactly 1 digit after the "E", your
format would be "##.00E+0". (Actually, in Canada, you folks might use a
"," instead of a "." for the decimal point; if you do, then you would
put the locally correct symbol in there.) In a format string, you can
put the format for a positive value, a negative value, and 0 seperated
by semicolons (e.g. "##.00E+0;-##.00E+0;0.00E+0").
But myFormatRec is not the format string itself, but is an internal
format that you get from calling StringToFormatRec. This is so you can
store the format returned to you by StringToFormatRec and use it on
different international systems. There is a nice editor for ResEdit for
'FMAT' resources that lets you type the format string and will call
StringToFormatRec for you and create an 'FMAT' resource out of the
result. Then you can load the 'FMAT' at run time and pass it to
The number parts table from the 'itl4' resource. If you are using
System 7 or later, you call GetIntlResourceTable, asking it for the
number parts table. You don't need to worry about HLock'ing itlHandle
because StringToExtended doesn't move memory; just don't do anything
between your call to GetIntlResourceTable and the StringToFormatRec
routine. If you are using System 6, you need to perform the
GetIntlResourceTable by hand. It's a few lines of code; left as an
exercise to the reader.
The extended number to put the thing into.
So, let's say you expect the user to enter a string containing up to 5
digits in the integer with a thousand marker between the 3rd and fourth
digit, exactly two digits after the decimal, put it in parenthesis if
it's negative, and have it just be "0.00" if it's 0. (I will use "."
for the decimal and "," for the thousand marker. Here's the C code
(passing in the source string):
*code* Handle itlHandle; /* The 'itl4' resource handle */ long offset, length; /* Offset-length of parts table */ NumFormatStringRec myFormatRec; /* Canonical format record */ extended80 x; /* The number to put it into */ GetIntlResourceTable (smCurrentScript, smNumberPartsTable, &itlHandle, &offset, &length); StringToFormatRec ("\p##,###.00;(##,###.00);0.00", (NumberParts *)(*itlHandle + offset), &myFormatRec); StringToExtended (source, &myFormatRec, (NumberParts *)(*itlHandle + offset), &x); *end*
*code* Handle itlHandle; /* The 'itl4' resource handle */ long offset, length; /* Offset-length of parts table */ NumFormatStringRec **myFormatRec; /* Canonical format resource */ extended80 x; /* The number to put it into */ myFormatRec = (NumFormatStringRec **)GetResource('FMAT', MY_FMAT); GetIntlResourceTable (smCurrentScript, smNumberPartsTable, &itlHandle, &offset, &length); StringToExtended (source, *myFormatRec, (NumberParts *)(*itlHandle + offset), &x); *end*