Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Programming
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Databases
Mail Systems
openSolaris
Eclipse Documentation
Techotopia.com
Virtuatopia.com

How To Guides
Virtualization
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Windows
Problem Solutions
Privacy Policy

  




 

 

Thinking in C++ Vol 2 - Practical Programming
Prev Home Next

Locales

Perhaps the most notable difference in typical numeric computer output from country to country is the punctuator used to separate the integer and fractional parts of a real number. In the United States, a period denotes a decimal point, but in much of the world, a comma is expected instead. It would be quite inconvenient to do all your own formatting for locale-dependent displays. Once again, creating an abstraction that handles these differences solves the problem.

That abstraction is the locale. All streams have an associated locale object that they use for guidance on how to display certain quantities for different cultural environments. A locale manages the categories of culture-dependent display rules, which are defined as follows:

Category

Effect

collate

Allows comparing strings according to different, supported collating sequences.

ctype

Abstracts the character classification and conversion facilities found in <cctype>.

monetary

Supports different displays of monetary quantities.

numeric

Supports different display formats of real numbers, including radix (decimal point) and grouping (thousands) separators.

time

Supports various international formats for display of date and time.

messages

Scaffolding to implement context-dependent message catalogs (such as for error messages in different languages).

 

The following program illustrates basic locale behavior:

//: C04:Locale.cpp {-g++}{-bor}{-edg} {RunByHand}
// Illustrates effects of locales.
#include <iostream>
#include <locale>
using namespace std;
 
int main() {
locale def;
cout << def.name() << endl;
locale current = cout.getloc();
cout << current.name() << endl;
float val = 1234.56;
cout << val << endl;
// Change to French/France
cout.imbue(locale("french"));
current = cout.getloc();
cout << current.name() << endl;
cout << val << endl;
 
cout << "Enter the literal 7890,12: ";
cin.imbue(cout.getloc());
cin >> val;
cout << val << endl;
cout.imbue(def);
cout << val << endl;
} ///:~
 

Here s the output:

C
C
1234.56
French_France.1252
1234,56
Enter the literal 7890,12: 7890,12
7890,12
7890.12
 

The default locale is the C locale, which is what C and C++ programmers have been used to all these years (basically, English language and American culture). All streams are initially imbued with the C locale. The imbue( ) member function changes the locale that a stream uses. Notice that the full ISO name for the French locale is displayed (that is, French used in France vs. French used in another country). This example shows that this locale uses a comma for a radix point in numeric display. We have to change cin to the same locale if we want to do input according to the rules of this locale.

Each locale category is divided into number of facets, which are classes encapsulating the functionality that pertains to that category. For example, the time category has the facets time_put and time_get, which contain functions for doing time and date input and output respectively. The monetary category has facets money_get, money_put, and moneypunct. (The latter facet determines the currency symbol.) The following program illustrates the moneypunct facet. (The time facet requires a sophisticated use of iterators which is beyond the scope of this chapter.)

//: C04:Facets.cpp {-bor}{-g++}{-mwcc}{-edg}
#include <iostream>
#include <locale>
#include <string>
using namespace std;
 
int main() {
// Change to French/France
locale loc("french");
cout.imbue(loc);
string currency =
use_facet<moneypunct<char> >(loc).curr_symbol();
char point =
use_facet<moneypunct<char> >(loc).decimal_point();
cout << "I made " << currency << 12.34 << " today!"
<< endl;
} ///:~
 

The output shows the French currency symbol and decimal separator:

I made 12,34 today!
 

You can also define your own facets to construct customized locales.[49] Be aware that the overhead for locales is considerable. In fact, some library vendors provide different flavors of the Standard C++ library to accommodate environments that have limited space.[50]

Thinking in C++ Vol 2 - Practical Programming
Prev Home Next

 
 
   Reproduced courtesy of Bruce Eckel, MindView, Inc. Design by Interspire