]> git.saurik.com Git - apple/icu.git/blame - icuSources/samples/numfmt/main.cpp
ICU-461.12.tar.gz
[apple/icu.git] / icuSources / samples / numfmt / main.cpp
CommitLineData
b75a7d8f
A
1/********************************************************************
2 * COPYRIGHT:
729e4ab9 3 * Copyright (c) 1999-2010, International Business Machines Corporation and
b75a7d8f
A
4 * others. All Rights Reserved.
5 ********************************************************************/
6
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"
14#include "util.h"
15#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
18
19#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0]))
20
21extern "C" void capi();
22void cppapi();
23
24static void
25showCurrencyFormatting(UBool useICU26API);
26
27int main(int argc, char **argv) {
28 printf("%s output is in UTF-8\n", argv[0]);
29
30 printf("C++ API\n");
31 cppapi();
32
33 printf("C API\n");
34 capi();
35
36 showCurrencyFormatting(FALSE);
37 showCurrencyFormatting(TRUE);
38
39 u_cleanup(); // Release any additional storage held by ICU.
40
41 printf("Exiting successfully\n");
42 return 0;
43}
44
45/**
46 * Sample code for the C++ API to NumberFormat.
47 */
48void cppapi() {
49 Locale us("en", "US");
50 UErrorCode status = U_ZERO_ERROR;
51
52 // Create a number formatter for the US locale
53 NumberFormat *fmt = NumberFormat::createInstance(us, status);
54 check(status, "NumberFormat::createInstance");
55
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");
59 Formattable result;
60 fmt->parse(str, result, status);
61 check(status, "NumberFormat::parse");
62
63 printf("NumberFormat::parse(\""); // Display the result
64 uprintf(str);
65 printf("\") => ");
66 uprintf(formattableToString(result));
67 printf("\n");
68
69 // Take the number parsed above, and use the formatter to
70 // format it.
71 str.remove(); // format() will APPEND to this string
72 fmt->format(result, str, status);
73 check(status, "NumberFormat::format");
74
75 printf("NumberFormat::format("); // Display the result
76 uprintf(formattableToString(result));
77 printf(") => \"");
78 uprintf(str);
79 printf("\"\n");
80
81 delete fmt; // Release the storage used by the formatter
82
83}
84
85// currency formatting ----------------------------------------------------- ***
86
87/*
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.
91 *
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
98 * the currency.
99 * @param currency The 3-letter ISO 4217 currency code, NUL-terminated.
100 * @param errorCode ICU error code, must pass U_SUCCESS() on input.
101 */
102static void
103setNumberFormatCurrency_2_4(NumberFormat &nf, const char *currency, UErrorCode &errorCode) {
104 // argument checking
105 if(U_FAILURE(errorCode)) {
106 return;
107 }
108 if(currency==NULL || strlen(currency)!=3) {
109 errorCode=U_ILLEGAL_ARGUMENT_ERROR;
110 return;
111 }
112
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
729e4ab9
A
116 DecimalFormat *dnf=dynamic_cast<DecimalFormat *>(&nf);
117 if(dnf==NULL) {
b75a7d8f
A
118 errorCode=U_ILLEGAL_ARGUMENT_ERROR;
119 return;
120 }
121
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 {
128 // ISO currency ID
129 const char *currency;
130
131 // fractionDigits==minimumFractionDigits==maximumFractionDigits
132 // for these currencies
133 int32_t fractionDigits;
134
135 /*
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).
142 */
143 double roundingIncrement;
144
145 // Unicode string with the desired currency display symbol or name
146 UChar symbol[16];
147 } currencyMap[]={
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 } }
152 };
153
154 int32_t i;
155
156 for(i=0; i<LENGTHOF(currencyMap); ++i) {
157 if(strcmp(currency, currencyMap[i].currency)==0) {
158 break;
159 }
160 }
161 if(i==LENGTHOF(currencyMap)) {
162 // a more specific error code would be useful in a real application
163 errorCode=U_UNSUPPORTED_ERROR;
164 return;
165 }
166
167 // set the currency-related data into the caller's formatter
168
169 nf.setMinimumFractionDigits(currencyMap[i].fractionDigits);
170 nf.setMaximumFractionDigits(currencyMap[i].fractionDigits);
171
729e4ab9 172 dnf->setRoundingIncrement(currencyMap[i].roundingIncrement);
b75a7d8f 173
729e4ab9 174 DecimalFormatSymbols symbols(*dnf->getDecimalFormatSymbols());
b75a7d8f 175 symbols.setSymbol(DecimalFormatSymbols::kCurrencySymbol, currencyMap[i].symbol);
729e4ab9 176 dnf->setDecimalFormatSymbols(symbols); // do not adopt symbols: Jitterbug 2889
b75a7d8f
A
177}
178
179/*
180 * Set a currency on a NumberFormat with ICU 2.6 APIs.
181 *
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
187 * the currency.
188 * @param currency The 3-letter ISO 4217 currency code, NUL-terminated.
189 * @param errorCode ICU error code, must pass U_SUCCESS() on input.
190 */
191static void
192setNumberFormatCurrency_2_6(NumberFormat &nf, const char *currency, UErrorCode &errorCode) {
193 if(U_FAILURE(errorCode)) {
194 return;
195 }
196 if(currency==NULL || strlen(currency)!=3) {
197 errorCode=U_ILLEGAL_ARGUMENT_ERROR;
198 return;
199 }
200
201 // invariant-character conversion to UChars (see utypes.h and putil.h)
202 UChar uCurrency[4];
203 u_charsToUChars(currency, uCurrency, 4);
204
205 // set the currency
374ca955
A
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)
b75a7d8f 208 nf.setCurrency(uCurrency);
374ca955
A
209#else
210 nf.setCurrency(uCurrency, errorCode);
211#endif
b75a7d8f
A
212}
213
214static const char *const
215sampleLocaleIDs[]={
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"
219};
220
221static const char *const
222sampleCurrencies[]={
223 "USD", "GBP", "EUR", "JPY"
224};
225
226static void
227showCurrencyFormatting(UBool useICU26API) {
228 NumberFormat *nf;
229 int32_t i, j;
230
231 UnicodeString output;
232
233 UErrorCode errorCode;
234
235 // TODO: Using printf() here assumes that the runtime encoding is ASCII-friendly
236 // and can therefore be mixed with UTF-8
237
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",
241 sampleLocaleIDs[i]);
242
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));
249 continue;
250 }
251
252 for(j=0; j<LENGTHOF(sampleCurrencies); ++j) {
253 printf(" - format currency \"%s\": ", sampleCurrencies[j]);
254
255 // set the actual currency to be formatted
256 if(useICU26API) {
257 setNumberFormatCurrency_2_6(*nf, sampleCurrencies[j], errorCode);
258 } else {
259 setNumberFormatCurrency_2_4(*nf, sampleCurrencies[j], errorCode);
260 }
261 if(U_FAILURE(errorCode)) {
262 printf("setNumberFormatCurrency(%s) failed - %s\n",
263 sampleCurrencies[j], u_errorName(errorCode));
264 continue;
265 }
266
267 // output=formatted currency value
268 output.remove();
269 nf->format(12345678.93, output);
270 output+=(UChar)0x0a; // '\n'
271 uprintf(output);
272 }
273 }
274}