Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
Разработка программного обеспечения

Boost.Locale: Introduction to C++ Standard Library localization support

Boost , ,

Introduction to C++ Standard Library localization support

Getting familiar with standard C++ Locales

Стандартная библиотека C++ предлагает простой и мощный способ предоставления локальной информации. Это делается с помощью класса<std::locale>, контейнера, который содержит всю необходимую информацию о конкретной культуре, такую как шаблоны форматирования чисел, форматирование даты и времени, валюта, конвертация корпуса и т. Д.

Вся эта информация представлена гранями, специальными классами, полученными из базового класса<std::locale::facet>. Такие грани упакованы в класс<std::locale>и позволяют предоставлять произвольную информацию о местности. Класс<std::locale>сохраняет счетчики ссылок на установленных гранях и может быть эффективно скопирован.

Каждая грань, установленная в<std::locale>объект, может быть извлечена с помощью функции<std::use_facet>. Например, грань<std::ctype<Char>>предоставляет правила для преобразования регистра, так что вы можете преобразовать символ в верхний регистр, как это:

std::ctype<char> const &ctype_facet = std::use_facet<std::ctype<char> >(some_locale);
char upper_a = ctype_facet.toupper('a');

Объект локализации может быть встроен в<iostream>, чтобы он форматировал информацию в соответствии с локализацией:

cout.imbue(std::locale("en_US.UTF-8"));
cout << 1345.45 << endl;
cout.imbue(std::locale("ru_RU.UTF-8"));
cout << 1345.45 << endl;

Показать бы:

    1,345.45 1.345,45

Вы также можете создать свои собственные грани и установить их в существующие локальные объекты. Например:

class measure : public std::locale::facet {
public:
typedef enum { inches, ... } measure_type;
measure(measure_type m,size_t refs=0)
double from_metric(double value) const;
std::string name() const;
...
};

И теперь вы можете просто предоставить эту информацию в местность:

std::locale::global(std::locale(std::locale("en_US.UTF-8"),new measure(measure::inches)));
/// Create default locale built from en_US locale and add paper size facet.

Теперь вы можете распечатать расстояние в соответствии с правильным местоположением:

void print_distance(std::ostream &out,double value)
{
measure const &m = std::use_facet<measure>(out.getloc());
// Fetch locale information from stream
out << m.from_metric(value) << " " << m.name();
}

Эта техника была принята Boost. Локальная библиотека для обеспечения мощной и правильной локализации. Вместо того, чтобы использовать очень ограниченные грани стандартной библиотеки C++, он использует ICU под капотом, чтобы создать свои собственные гораздо более мощные.

Common Critical Problems with the Standard Library

В стандартной библиотеке существует множество проблем, препятствующих использованию ее полной мощности, и есть несколько дополнительных проблем:

  • Установка глобальной локализации имеет плохие побочные эффекты.
    Рассмотрим следующий код:
    intmain()
    {
    std::locale::global(""));
    // Установите System's по умолчанию локально как глобальный
    std::ofstream csv"test.csv";
    csv<< 1.1<<","<< 1.3<< std::endl;

    Каково будет содержаниеtest.csv? Это может быть «1.1,1.3» или «1,1,1,3», а не то, что вы ожидали.
    Более того, это влияет даже наprintfи библиотеки, подобныеboost::lexical_cast, давая неправильное или неожиданное форматирование. На самом деле многие сторонние библиотеки разбиты в такой ситуации.
    В отличие от стандартной библиотеки локализации, Boost. Locale никогда не меняет базовое форматирование чисел, даже когда он используетstdбэкэнды локализации, поэтому по умолчанию номера всегда отформатированы с использованием C-стиля locale. Для локализованного форматирования номеров требуются специальные флаги.

    What would be the content of test.csv ? It may be "1.1,1.3" or it may be "1,1,1,3" rather than what you had expected.
    More than that it affects even printf and libraries like boost::lexical_cast giving incorrect or unexpected formatting. In fact many third-party libraries are broken in such a situation.
    Unlike the standard localization library, Boost.Locale never changes the basic number formatting, even when it uses std based localization backends, so by default, numbers are always formatted using C-style locale. Localized number formatting requires specific flags.
    [ORIG_END] -->
  • Форматирование номеров нарушается в некоторых местах.
    Некоторые локали используют символ неразрывного пространства u00A0 для тысяч сепараторов, поэтому вru_RU.UTF-8локальном номере 1024 следует отображать как «1 024», где пространство является символом Unicode с кодовой точкой u00A0. К сожалению, многие библиотеки не справляются с этим правильно, например, GCC и SunStudio отображают символ «\xC2» вместо первого символа в последовательности UTF-8 «\xC2\xA0», который представляет эту точку кода, и фактически генерируют недействительный UTF-8.
  • Местные названия не стандартизированы. Например, под MSVC нужно указать имяen-USилиEnglish_USA.1252, когда на платформах POSIX оно будетen_US.UTF-8илиen_US.ISO-8859-1.
    Более того, MSVC вообще не поддерживает UTF-8.
  • Многие стандартные библиотеки предоставляют только локализации C и POSIX, поэтому GCC поддерживает локализацию только под Linux. На всех других платформах попытка создать локализации, отличные от «C» или «POSIX», не увенчалась бы успехом.

Статья Boost.Locale: Introduction to C++ Standard Library localization support раздела может быть полезна для разработчиков на c++ и boost.




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.



:: Главная :: ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-08-30 11:47:00
2025-05-20 08:36:49/0.0064220428466797/0