]>
git.saurik.com Git - apple/icu.git/blob - icuSources/samples/numfmt/main.cpp
1 /********************************************************************
3 * Copyright (c) 1999-2010, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ********************************************************************/
7 #include "unicode/utypes.h"
8 #include "unicode/unistr.h"
9 #include "unicode/numfmt.h"
10 #include "unicode/dcfmtsym.h"
11 #include "unicode/decimfmt.h"
12 #include "unicode/locid.h"
13 #include "unicode/uclean.h"
19 #define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
21 extern "C" void capi();
25 showCurrencyFormatting(UBool useICU26API
);
27 int main(int argc
, char **argv
) {
28 printf("%s output is in UTF-8\n", argv
[0]);
36 showCurrencyFormatting(FALSE
);
37 showCurrencyFormatting(TRUE
);
39 u_cleanup(); // Release any additional storage held by ICU.
41 printf("Exiting successfully\n");
46 * Sample code for the C++ API to NumberFormat.
49 Locale
us("en", "US");
50 UErrorCode status
= U_ZERO_ERROR
;
52 // Create a number formatter for the US locale
53 NumberFormat
*fmt
= NumberFormat::createInstance(us
, status
);
54 check(status
, "NumberFormat::createInstance");
56 // Parse a string. The string uses the digits '0' through '9'
57 // and the decimal separator '.', standard in the US locale
58 UnicodeString
str("9876543210.123");
60 fmt
->parse(str
, result
, status
);
61 check(status
, "NumberFormat::parse");
63 printf("NumberFormat::parse(\""); // Display the result
66 uprintf(formattableToString(result
));
69 // Take the number parsed above, and use the formatter to
71 str
.remove(); // format() will APPEND to this string
72 fmt
->format(result
, str
, status
);
73 check(status
, "NumberFormat::format");
75 printf("NumberFormat::format("); // Display the result
76 uprintf(formattableToString(result
));
81 delete fmt
; // Release the storage used by the formatter
85 // currency formatting ----------------------------------------------------- ***
88 * Set a currency on a NumberFormat with pre-ICU 2.6 APIs.
89 * This is a "hack" that will not work properly for all cases because
90 * only ICU 2.6 introduced a more complete framework and data for this.
92 * @param nf The NumberFormat on which to set the currency; takes effect on
93 * currency-formatting NumberFormat instances.
94 * This must actually be a DecimalFormat instance.
95 * The display style of the output is controlled by nf (its pattern,
96 * usually from the display locale ID used to create this instance)
97 * while the currency symbol and number of decimals are set for
99 * @param currency The 3-letter ISO 4217 currency code, NUL-terminated.
100 * @param errorCode ICU error code, must pass U_SUCCESS() on input.
103 setNumberFormatCurrency_2_4(NumberFormat
&nf
, const char *currency
, UErrorCode
&errorCode
) {
105 if(U_FAILURE(errorCode
)) {
108 if(currency
==NULL
|| strlen(currency
)!=3) {
109 errorCode
=U_ILLEGAL_ARGUMENT_ERROR
;
113 // check that the formatter is a DecimalFormat instance
114 // necessary because we will cast to the DecimalFormat subclass to set
115 // the currency symbol
116 DecimalFormat
*dnf
=dynamic_cast<DecimalFormat
*>(&nf
);
118 errorCode
=U_ILLEGAL_ARGUMENT_ERROR
;
122 // map the currency code to a locale ID
123 // only the currencies in this array are supported
124 // it would be possible to map to a locale ID, instantiate a currency
125 // formatter for that and copy its values, but that would be slower,
126 // and we have to hardcode something here anyway
127 static const struct {
129 const char *currency
;
131 // fractionDigits==minimumFractionDigits==maximumFractionDigits
132 // for these currencies
133 int32_t fractionDigits
;
136 * Set the rounding increment to 0 if it is implied with the number of
137 * fraction digits. Setting an explicit rounding increment makes
138 * number formatting slower.
139 * In other words, set it to something other than 0 only for unusual
140 * cases like "nickel rounding" (0.05) when the increment differs from
141 * 10^(-maximumFractionDigits).
143 double roundingIncrement
;
145 // Unicode string with the desired currency display symbol or name
148 { "USD", 2, 0.0, { 0x24, 0 } },
149 { "GBP", 2, 0.0, { 0xa3, 0 } },
150 { "EUR", 2, 0.0, { 0x20ac, 0 } },
151 { "JPY", 0, 0.0, { 0xa5, 0 } }
156 for(i
=0; i
<LENGTHOF(currencyMap
); ++i
) {
157 if(strcmp(currency
, currencyMap
[i
].currency
)==0) {
161 if(i
==LENGTHOF(currencyMap
)) {
162 // a more specific error code would be useful in a real application
163 errorCode
=U_UNSUPPORTED_ERROR
;
167 // set the currency-related data into the caller's formatter
169 nf
.setMinimumFractionDigits(currencyMap
[i
].fractionDigits
);
170 nf
.setMaximumFractionDigits(currencyMap
[i
].fractionDigits
);
172 dnf
->setRoundingIncrement(currencyMap
[i
].roundingIncrement
);
174 DecimalFormatSymbols
symbols(*dnf
->getDecimalFormatSymbols());
175 symbols
.setSymbol(DecimalFormatSymbols::kCurrencySymbol
, currencyMap
[i
].symbol
);
176 dnf
->setDecimalFormatSymbols(symbols
); // do not adopt symbols: Jitterbug 2889
180 * Set a currency on a NumberFormat with ICU 2.6 APIs.
182 * @param nf The NumberFormat on which to set the currency; takes effect on
183 * currency-formatting NumberFormat instances.
184 * The display style of the output is controlled by nf (its pattern,
185 * usually from the display locale ID used to create this instance)
186 * while the currency symbol and number of decimals are set for
188 * @param currency The 3-letter ISO 4217 currency code, NUL-terminated.
189 * @param errorCode ICU error code, must pass U_SUCCESS() on input.
192 setNumberFormatCurrency_2_6(NumberFormat
&nf
, const char *currency
, UErrorCode
&errorCode
) {
193 if(U_FAILURE(errorCode
)) {
196 if(currency
==NULL
|| strlen(currency
)!=3) {
197 errorCode
=U_ILLEGAL_ARGUMENT_ERROR
;
201 // invariant-character conversion to UChars (see utypes.h and putil.h)
203 u_charsToUChars(currency
, uCurrency
, 4);
206 // in ICU 3.0 this API (which was @draft ICU 2.6) gained a UErrorCode& argument
207 #if (U_ICU_VERSION_MAJOR_NUM < 3)
208 nf
.setCurrency(uCurrency
);
210 nf
.setCurrency(uCurrency
, errorCode
);
214 static const char *const
216 // use locale IDs complete with country code to be sure to
217 // pick up number/currency format patterns
218 "en_US", "en_GB", "de_DE", "ja_JP", "fr_FR", "hi_IN"
221 static const char *const
223 "USD", "GBP", "EUR", "JPY"
227 showCurrencyFormatting(UBool useICU26API
) {
231 UnicodeString output
;
233 UErrorCode errorCode
;
235 // TODO: Using printf() here assumes that the runtime encoding is ASCII-friendly
236 // and can therefore be mixed with UTF-8
238 for(i
=0; i
<LENGTHOF(sampleLocaleIDs
); ++i
) {
239 printf("show currency formatting (method for %s) in the locale \"%s\"\n",
240 useICU26API
? "ICU 2.6" : "before ICU 2.6",
243 // get a currency formatter for this locale ID
244 errorCode
=U_ZERO_ERROR
;
245 nf
=NumberFormat::createCurrencyInstance(sampleLocaleIDs
[i
], errorCode
);
246 if(U_FAILURE(errorCode
)) {
247 printf("NumberFormat::createCurrencyInstance(%s) failed - %s\n",
248 sampleLocaleIDs
[i
], u_errorName(errorCode
));
252 for(j
=0; j
<LENGTHOF(sampleCurrencies
); ++j
) {
253 printf(" - format currency \"%s\": ", sampleCurrencies
[j
]);
255 // set the actual currency to be formatted
257 setNumberFormatCurrency_2_6(*nf
, sampleCurrencies
[j
], errorCode
);
259 setNumberFormatCurrency_2_4(*nf
, sampleCurrencies
[j
], errorCode
);
261 if(U_FAILURE(errorCode
)) {
262 printf("setNumberFormatCurrency(%s) failed - %s\n",
263 sampleCurrencies
[j
], u_errorName(errorCode
));
267 // output=formatted currency value
269 nf
->format(12345678.93, output
);
270 output
+=(UChar
)0x0a; // '\n'