В настоящее время актуальный стандарт - это POSIX 2008 и его дополнение POSIX 1003.13 |
Языково-культурная среда
Программная установка и опрос характеристик языково-культурной среды
Мы приступаем к рассмотрению функций, предназначенных для работы с языково-культурной средой.
Функция setlocale() (см. листинг 13.9) служит для установки и/или опроса всей языково-культурной среды вызывающего процесса или отдельных категорий.
#include <locale.h> char *setlocale (int category, const char *locale);13.9. Описание функции setlocale().
Аргумент category задает категорию ( LC_COLLATE, LC_CTYPE, LC_MESSAGES, LC_MONETARY, LC_NUMERIC, LC_TIME ), а если его значение равно LC_ALL, то и всю среду.
Аргумент locale указывает на цепочку символов, содержащую требуемые установки для выбранной категории (категорий); в общем случае ее формат зависит от реализации. Имеется, однако, несколько предопределенных, стандартизованных цепочек.
"POSIX" или "C"
Специфицирует минимальную языково-культурную среду ( POSIX-среду ) для C-программ. При отсутствии явных обращений к функции setlocale() такая среда устанавливается по умолчанию при входе в main().
""
Специфицирует зависящую от реализации местную языково-культурную среду, определяемую значениями переменных окружения LC_* и LANG. Интернационализированная программа должна выполнять вызов вида
setlocale (LC_ALL, "");
для настройки на местную среду выполнения.
Если значением аргумента locale служит пустой указатель, функция setlocale() опрашивает текущее окружение и возвращает имя используемой языково-культурной среды или цепочку символов, ассоциированную с выбранной категорией. В противном случае в качестве результата возвращаются те же характеристики, но для новой среды. Результирующая цепочка (скопированная в отведенную прикладной программой область памяти) в сочетании с заданной категорией может быть использована в последующих вызовах функции setlocale() для восстановления соответствующей части языково-культурной среды.
Разумеется, в случае неудачного завершения вызова setlocale() результатом служит пустой указатель.
Получить детальную информацию о категориях LC_MONETARY и LC_NUMERIC текущей языково-культурной среды можно с помощью функции localeconv() (см. листинг 13.10).
#include <locale.h> struct lconv *localeconv (void);13.10. Описание функции localeconv().
Структура типа lconv была описана выше. Здесь мы отметим лишь два момента.
Поля, имеющие тип char *, указывают на цепочки символов, каждая из которых (за исключением *decimal_point ) может иметь вид "" как признак того, что данное значение в текущей среде недоступно или имеет нулевую длину.
Поля типа char содержат неотрицательные числа; CHAR_MAX указывает на то, что данное значение в текущей среде недоступно.
Вызов localeconv() не может кончиться неудачей, однако следует учитывать, что возвращаемая структура может быть перезаписана последующими обращениями не только к localeconv(), но и к setlocale().
Следующая программа (см. листинг 13.11) демонстрирует использование функций setlocale() и localeconv().
#include <stdio.h> #include <locale.h> /* Функция опрашивает и выводит цепочки символов, */ /* ассоциированные с текущей средой и ее */ /* категориями */ void print_curr_locale_data (void) { /* Массив категорий для setlocale() */ int ctgrs [] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MESSAGES, LC_MONETARY, LC_NUMERIC, LC_TIME}; /* Массив имен категорий */ char *ctgrnms [] = {"LC_ALL", "LC_COLLATE", "LC_CTYPE", "LC_MESSAGES", "LC_MONETARY", "LC_NUMERIC", "LC_TIME"}; unsigned int i; printf ("Цепочки символов, ассоциированные в текущей среде с\n"); for (i = 0; i < sizeof (ctgrs) / sizeof (int); i++) { printf (" %s: %s\n", ctgrnms [i], setlocale (ctgrs [i], NULL)); } } int main (void) { struct lconv *plc; /* Убедимся, что подразумеваемой является */ /* POSIX-среда */ printf ("Текущая языково-культурная среда: подразумеваемая\n"); print_curr_locale_data(); /* Установим местную среду */ (void) setlocale (LC_ALL, ""); /* Опросим и выдадим ее характеристики */ printf ("Текущая языково-культурная среда: местная\n"); print_curr_locale_data(); plc = localeconv (); printf ("Некоторые элементы категорий LC_MONETARY и LC_NUMERIC\n"); printf ("int_curr_symbol: %s\n", plc->int_curr_symbol); printf ("currency_symbol: %s\n", plc->currency_symbol); printf ("mon_decimal_point: %s\n", plc->mon_decimal_point); printf ("decimal_point: %s\n", plc->decimal_point); printf ("thousands_sep: %s\n", plc->thousands_sep); /* Сделаем "денежную" категорию украинской */ if (setlocale (LC_MONETARY, "ru_UA") == NULL) { perror ("SETLOCALE"); return (1); } printf ("Категория LC_MONETARY переустановлена для Украины\n"); print_curr_locale_data(); plc = localeconv (); printf ("Некоторые элементы категории LC_MONETARY\n"); printf ("int_curr_symbol: %s\n", plc->int_curr_symbol); printf ("currency_symbol: %s\n", plc->currency_symbol); return 0; }13.11. Пример использования функций setlocale() и localeconv().
Возможный результат работы этой программы показан в листинге 13.12.
Текущая языково-культурная среда: подразумеваемая Цепочки символов, ассоциированные в текущей среде с LC_ALL: C LC_COLLATE: C LC_CTYPE: C LC_MESSAGES: C LC_MONETARY: C LC_NUMERIC: C LC_TIME: C Текущая языково-культурная среда: местная Цепочки символов, ассоциированные в текущей среде с LC_ALL: ru_RU.koi8r LC_COLLATE: ru_RU.koi8r LC_CTYPE: ru_RU.koi8r LC_MESSAGES: ru_RU.koi8r LC_MONETARY: ru_RU.koi8r LC_NUMERIC: ru_RU.koi8r LC_TIME: ru_RU.koi8r Некоторые элементы категорий LC_MONETARY и LC_NUMERIC int_curr_symbol: RUR currency_symbol: РУБ mon_decimal_point: . decimal_point: , thousands_sep: . Категория LC_MONETARY переустановлена для Украины Цепочки символов, ассоциированные в текущей среде с LC_ALL: LC_CTYPE=ru_RU.koi8r;LC_NUMERIC=ru_RU.koi8r; LC_TIME=ru_RU.koi8r;LC_COLLATE=ru_RU.koi8r; LC_MONETARY=ru_UA;LC_MESSAGES=ru_RU.koi8r; LC_PAPER=ru_RU.koi8r;LC_NAME=ru_RU.koi8r; LC_ADDRESS=ru_RU.koi8r;LC_TELEPHONE=ru_RU.koi8r; LC_MEASUREMENT=ru_RU.koi8r; LC_IDENTIFICATION=ru_RU.koi8r LC_COLLATE: ru_RU.koi8r LC_CTYPE: ru_RU.koi8r LC_MESSAGES: ru_RU.koi8r LC_MONETARY: ru_UA LC_NUMERIC: ru_RU.koi8r LC_TIME: ru_RU.koi8r Некоторые элементы категории LC_MONETARY int_curr_symbol: UAH currency_symbol: ГР13.12. Возможный результат работы программы, использующей функции setlocale() и localeconv().
Для преобразования денежных величин в цепочку символов в соответствии с настройками текущей языково-культурной среды можно воспользоваться функцией strfmon() (см. листинг 13.13), входящей в XSI-расширение стандарта POSIX-2001.
#include <monetary.h> ssize_t strfmon (char *restrict s, size_t maxsize, const char *restrict format, ...);13.13. Описание функции strfmon().
Результат преобразования (длиной не более maxsize байт) помещается в буфер, на который указывает аргумент s. Само преобразование выполняется под управлением аргумента format. В формат могут входить обычные символы, просто копируемые в выходную цепочку, а также спецификаторы преобразований – под их воздействием производится извлечение и вывод дополнительных аргументов.
Спецификатор преобразования в общем случае состоит из следующих компонентов:
- символ %;
- флаги;
- ширина поля;
- число символов в целой части;
- число символов в дробной части;
- символ, задающий преобразование.
Обязательными являются только первый и последний компоненты. Возможных преобразований два:
i
Преобразовать значение типа double в денежную величину международного формата.
n
Преобразовать значение типа double в денежную величину местного формата.
В качестве результата функция strfmon() возвращает количество байт, помещенное в массив s.