Установка или изменение locale для программиста

Установка или изменение locale для программиста [Вперед] [Вверх] [Назад] [Содержание]
Дальше: Форматирование чисел и дежежных Вверх: Интернационализация Назад: Пример смешанного locale

Установка или изменение locale для программиста

Программам на языке C переменные окружения доступны либо через третий аргумент функции main, либо (что на самом деле то же самое) с помощью функций getenv и putenv. Однако даже если переменная окружения LANG либо какие-то переменные из перечисленных выше установлены, автоматической установки locale не происходит. Стандарт ISO на язык C требует, чтобы выполнение программы начиналось (и продолжалось -- при отсутствии каких-либо специальных действий) в locale по умолчанию -- C(POSIX) - locale. Специальным же действием для установки нужного locale является вызов функции setlocale. Например, такой вызов

    setlocale (LC_ALL, "");

устанавливает locale, основываясь на значениях переменных окружения. Функцию setlocale можно использовать и для установки locale отдельно для каждой категории. Для использования функции setlocale нужно подключать заголовочный файл locale.h. Прототип функции setlocale описан в этом файле следующим образом:

extern char *setlocale (int category, const char *locale);

Корректное использование функции setlocale предполагает выполнение следующих соглашений:

  • при любых ошибках возвращается NULL и текущее locale остается неизменным;
  • если аргумент category равен LC_ALL, то указанное locale устанавливается для всех категорий; иначе значение параметра category должно быть одним из LC_CTYPE, LC_NUMERIC, LC_TIME, LC_COLLATE, LC_MONETARY, LC_MESSAGES;
  • если параметр locale равен ``'' (пустой строке), то устанавливается locale, специфицированное соответствующей переменной окружения; например, вызов
    setlocale (LC_NUMERIC, ``'')
    
    приведет к установлению категории locale, отвечающей за представление числовых величин, соответственно значению переменной окружения LC_NUMERIC. Такой вызов завершится ошибкой, если такая переменная содержит некорректное значение (имя несуществующего locale); если же соответствующая переменная не установлена, то будет возвращено имя текущего locale;
  • если параметр locale равен NULL, возвращается имя текущего locale в соответствии со значением параметра category. Возвращаемая строка может быть перезаписана последующими вызовами setlocale, поэтому в слючае дальнейшего использования она должна быть скопирована. Явное изменение этой строки нежелательно, так как она может быть той же самой строкой, которая была использована в предыдушем вызове setlocale.

Ниже приведен пример программы, иллюстрирующей поведение функции setlocale:

/*
 * setlocale.c
 * Пример программы, устанавливающей locale.
 */

#include <stdio.h>
#include <locale.h> /* Для функции setlocale и т.п. */
#include <string.h>
#include <stdlib.h>

#ifdef _GNU_SOURCE
/* Переменная содержит "базовое" имя программы (basename) */
extern char *program_invocation_short_name;
#else
const char *program_name;
#define program_invocation_short_name program_name
#endif /* _GNU_SOURCE */

int main (int argc, char *argv[]) {
  char *locale = ""; 
  char *start_locale, *current_locale;
  char *lang;
#ifndef _GNU_SOURCE
  program_name = argv[0];
#endif

  if (argc < 2 ) 
    fprintf (stderr, "%s: setting locale based on $LANG env value\n", 
             program_invocation_short_name);
  else
    locale = argv[1];
  /* Только для распечатки значения - setlocale сама делает getenv("LANG") */
  lang = getenv ("LANG");

  start_locale = setlocale (LC_ALL, NULL);
  if ((current_locale = setlocale (LC_ALL, locale)) == NULL) 
    fprintf (stderr, "%s: failed to set locale %s (LANG=`%s')\n",
             program_invocation_short_name, locale, lang);
  else 
    printf ("%s: start locale: `%s', current locale: `%s'\n", 
            program_invocation_short_name, start_locale, current_locale);
  return 0;
}

При компиляции программы с GNU glibc можно указать макрос, сигнализирующий о том, что вы хотите использовать GNU-расширения C-библиотеки, примерно так:

[user@host:~] gcc -D_GNU_SOURCE -Wall -O3 setlocale.c -o setlocale



Dmitry A. Antipov
1999-05-26