Опубликован: 15.06.2004 | Доступ: свободный | Студентов: 2557 / 712 | Оценка: 4.35 / 3.96 | Длительность: 27:47:00
ISBN: 978-5-9556-0011-6
Лекция 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.

Антон Коновалов
Антон Коновалов

В настоящее время актуальный стандарт - это POSIX 2008 и его дополнение POSIX 1003.13
Планируется ли актуализация материалов данного очень полезного курса?