Cpp Libs Locale
## C++ Standard Library: ``
In the C++ Standard Library, the `` header provides a robust mechanism to control localization behaviors. It allows programs to adapt to language- and culture-specific formatting, parsing, and translation rules.
By utilizing the `std::locale` class and its associated facets, you can easily handle text data according to a user's regional settings. This includes formatting numbers, currencies, dates, and times, as well as performing locale-sensitive string comparisons and character classifications. This is a fundamental tool for building internationalized (i18n) and localized (l10n) applications.
---
### Syntax and Basic Usage
To use the `locale` class, include the `` header. Below is the basic syntax for instantiating and applying a locale:
```cpp
#include
#include
int main() {
// Create a default locale object (usually the "C" locale by default)
std::locale loc;
// Apply (imbue) the locale object onto an input/output stream
std::cout.imbue(loc);
// Display the name of the current locale
std::cout << "Current locale: " << loc.name() << std::endl;
return 0;
}
```
---
### Key Concepts: Locales and Facets
A `std::locale` object is an immutable collection of **facets**. Each facet is a class that handles a specific aspect of localization:
* **`std::collate`**: Controls string collation (comparison and sorting order).
* **`std::num_get` / `std::num_put`**: Handles parsing and formatting of numeric values.
* **`std::numpunct`**: Defines numeric punctuation rules (such as decimal points and thousands separators).
* **`std::time_get` / `std::time_put`**: Handles parsing and formatting of dates and times.
* **`std::moneypunct` / `std::money_get` / `std::money_put`**: Handles monetary formatting and parsing.
* **`std::ctype`**: Handles character classification (e.g., checking if a character is alphanumeric) and case conversions.
---
### Code Examples
#### 1. Basic Number Formatting
The following example demonstrates how to use `std::locale` to format numbers with regional punctuation (such as thousands separators):
```cpp
#include
#include
int main() {
try {
// Set the locale to US English
std::locale loc("en_US.UTF-8");
// Imbue the locale onto std::cout
std::cout.imbue(loc);
double number = 1234567.89;
std::cout << "Formatted number: " << number << std::endl;
} catch (const std::runtime_error& e) {
std::cerr << "Locale error: " << e.what() << std::endl;
}
return 0;
}
```
**Output**:
```text
Formatted number: 1,234,567.89
```
---
#### 2. Locale-Sensitive String Comparison
Using `std::collate` allows you to compare strings according to the alphabetical rules of a specific region, rather than a simple binary ASCII comparison.
```cpp
#include
#include
#include
int main() {
try {
std::locale loc("en_US.UTF-8");
std::string str1 = "apple";
std::string str2 = "banana";
// Retrieve the collate facet from the locale
const auto& coll = std::use_facet>(loc);
// Compare the two strings using the facet
int result = coll.compare(str1.c_str(), str1.c_str() + str1.size(),
str2.c_str(), str2.c_str() + str2.size());
if (result < 0) {
std::cout << str1 << " comes before " << str2 << std::endl;
} else if (result > 0) {
std::cout << str1 << " comes after " << str2 << std::endl;
} else {
std::cout << str1 << " is equivalent to " << str2 << std::endl;
}
} catch (const std::runtime_error& e) {
std::cerr << "Locale error: " << e.what() << std::endl;
}
return 0;
}
```
**Output**:
```text
apple comes before banana
```
---
#### 3. Date and Time Formatting
You can use `std::locale` in combination with time-formatting functions to output dates and times in a localized format.
```cpp
#include
#include
#include
int main() {
try {
// Set the locale to US English
std::locale loc("en_US.UTF-8");
std::cout.imbue(loc);
std::time_t now = std::time(nullptr);
std::tm* timeinfo = std::localtime(&now);
char buffer;
// Format the date using strftime, which respects the imbued locale
std::strftime(buffer, sizeof(buffer), "%A, %B %d, %Y", timeinfo);
std::cout << "Current date: " << buffer << std::endl;
} catch (const std::runtime_error& e) {
std::cerr << "Locale error: " << e.what() << std::endl;
}
return 0;
}
```
**Output** (Example):
```text
Current date: Monday, March 14, 2023
```
---
### Important Considerations
1. **Platform Dependency**: Locale names (e.g., `"en_US.UTF-8"`, `"en-US"`, or `"English_United States"`) are highly dependent on the operating system and installed system packages. If a requested locale is not supported by the host system, the `std::locale` constructor will throw a `std::runtime_error`.
2. **The System Default Locale**: You can instantiate a locale using the user's system settings by passing an empty string to the constructor: `std::locale loc("")`.
3. **Performance**: Querying facets and formatting stream data using locales can introduce minor runtime overhead. For performance-critical, non-user-facing operations (like writing JSON or CSV files), it is recommended to stick to the default `"C"` locale.
YouTip