[ Страница назад | Страница вперед | Содержание | Индекс | Библиотека | Юридическая информация | Поиск ]

Программирование: Разработка и отладка программ


Функции работы с локалями

Локаль, соответствующая процессу, определяет последовательность упорядочения символов, классификацию символов, формат даты и времени, формат записи чисел и денежных величин, а также способ обработки выводимых сообщений. Следующий раздел посвящен выбору локали и считыванию информации о локали с помощью функций Поддержки национальных языков (NLS).

Выбор локали

В любой международной программе локаль должна устанавливаться функцией setlocale

. Эта функция позволяет процессу обращаться к базам данных локалей для изменения или опроса текущей локали.

При запуске процесса по умолчанию устанавливается локаль С или POSIX. Программа, зависящая от данных локали, не определенных в локали C или POSIX, должна до начала работы с любыми такими данными вызвать функцию setlocale

. Синтаксис вызова:

setlocale(LC_ALL, "");

Доступ к информации о локали

Перечисленные ниже функции обеспечивают доступ к информации о текущей локали, установленной при последнем вызове функции setlocale

:

localeconv

Предоставляет доступ к категориям LC_MONETARY и LC_NUMERIC текущей локали. Функция localeconv считывает информацию об этих категориях, помещает ее в структуру типа lconv, определенную в файле locale.h , и возвращает указатель на эту структуру.
nl_langinfo

Возвращает указатель на строку, оканчивающуюся символом NULL и содержащую информацию о категориях LC_CTYPE, LC_MESSAGES, LC_MONETARY, LC_NUMERIC и LC_TIME текущей локали.
rpmatch

Проверяет наличие утвердительных и отрицательных ответов. Ответы определены в категории LC_MESSAGES текущей локали. Ответы могут быть регулярными выражениями или простыми строками. Функция rpmatch не входит в число стандартных функций. Если вы хотите создать переносимое приложение, не следует вызывать эту функцию.

Функции localeconv и nl_langinfo не обеспечивают доступа ко всем категориям LC_*

.

Для определения текущего значения какой-либо категории локали следует вызвать функцию setlocale(категория(char*)0). Функция возвращает строку, содержащую имя текущей локали для указанной категории. В приведенном ниже примере определяется текущая локаль для категории LC_CTYPE:

char *ctype_locale; ctype_locale = setlocale(LC_CTYPE, (char*)0);

Примеры

  1. В этом примере функция setlocale

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

    #include <locale.h>
    main()
    {
     
        char *p;
     
        p = setlocale(LC_ALL, "");
      
       /*
        **  В программе будут использоваться
        **  переменные LC_* и LANG.
        */ 
     }
    
  2. В следующем примере

    функция setlocale

    применяется для определения текущей локали для категории LC_COLLATE :

    #include <stdio.h>
    #include <locale.h>
     
    main()
    {
        char *p;
     
        /*  установка текущей локали */
        p = setlocale(LC_ALL, "");
        /*  p указывает на параметры всех категорий
        **  локали
        */
     
        /*
        **  определение текущего значения категории
        **  LC_COLLATE
        */
        p = setlocale(LC_COLLATE, NULL);
        /*
        **  p указывает на строку с текущим значением
        **  категории LC_COLLATE.
        */
      
     } 
    
  3. В следующем примере

    функция setlocale

    применяется для определения текущих установок локали и сохранения этих установок. Таким образом, программа может временно изменить текущую локаль. После завершения работы можно восстановить исходную локаль.

    #include <stdio.h>
    #include <locale.h>
    #include <string.h>
      
    #define NEW_LOCALE "MY_LOCALE"
      
    main()
    {
        char *p, *save_locale;
     
        p = setlocale(LC_ALL, ""); 
        /*
        **  инициализация указателя на локаль. p указывает на область
        **  значений всех категорий локали
        */
     
        save_locale = (char *)malloc(strlen(p) +1); 
        strcpy(save_locale, p);
            /*  сохранение текущих параметров локали */
        p = setlocale(LC_ALL, NEW_LOCALE);
            /* Установить новую локаль */
      
        /*
        **  выполнить требуемые действия ...
        */
     
         /*  возврат к исходной локали  */
        p = setlocale(LC_ALL, save_locale);  /* возврат к исходной локали */
     
         free(save_locale);    /* Освобождение памяти */
    }
    
  4. В следующем примере

    функция setlocale

    применяется для приведения категории LC_MESSAGES в соответствие со значениями переменных среды. Для всех остальных категорий текущей локалью остается локаль С.

    #include <locale.h>
     
    main() 
    { 
        char *p;
     
        /*
           **  программа запущена в локали C по всем категориям
        */
     
        p = setlocale(LC_MESSAGES, "");
     
         /*
        **  в данный момент категории LC_COLLATE, LC_CTYPE, LC_NUMERIC,
        **  LC_MONETARY, LC_TIME установлены в локаль C.
        **  категория LC_MESSAGES установлена в текущую локаль
        **  согласно значениям переменных среды.
        */
    }
    
  5. В следующем примере

    функция localeconv

    применяется для считывания значения десятичного разделителя в текущей локали:

    #include <locale.h>
     
    main()
    {
            struct lconv *ptr;
            char *decimal;
     
            (void)setlocale(LC_ALL, "");
            ptr = localeconv();
            /*
            ** Обработать полученные данные. Например, определить
            ** текущее значение десятичного разделителя.
            */
            decimal = ptr->decimal_point;
    }
    
  6. В следующем примере

    функция nl_langinfo

    применяется для считывания формата даты и времени текущей локали:

    #include <langinfo.h>
    #include <locale.h>
    main()
    {
        char *ptr;
        (void)setlocale(LC_ALL, "");
        ptr = nl_langinfo(D_T_FMT);
    }
    
  7. В следующем примере

    функция nl_langinfo применяется для считывания представления символа квадратного корня в текущей локали:

    #include <langinfo.h>
    #include <locale.h>
     
    main()
    {
        char *ptr;
        (void)setlocale(LC_ALL, "");  /* Установка локали для программы */
        ptr = nl_langinfo(RADIXCHAR); /* Определение десятичного разделителя*/
    }
    
  8. В следующем примере

    функция nl_langinfo применяется для считывания символа валюты для текущей локали:

    #include <langinfo.h>
    #include <locale.h>
     
    main()
    {
        char *ptr;
        (void)setlocale(LC_ALL, "");  /* Установка локали программы */
        ptr = nl_langinfo(CRNCYSTR);  /* Определение символа валюты*/
        /* Для локали en_US символ валюты - "-$". */
    }
    
  9. В следующем примере

    функция rpmatch

    применяется для считывания строк утвердительного и отрицательного ответа для текущей локали:

    Утвердительный и отрицательный ответы, определенные в базе данных локалей, теперь могут быть не только простыми строками, но и регулярными выражениями. Например, yesexpr может быть приведенным ниже регулярным выражением, которое должно принимать прописную или строчную букву y, за которой может следовать несколько букв алфавита или не следовать ни одной, или же символ O, за которым следует символ K:

    ([yY][:alpha:]*|OK) 
    

    В стандартах не определена функция для считывания и сравнения этой информации. Можно применять определенную в AIX функцию rpmatch(const char *response).

    #include <stdio.h>
    #include <langinfo.h>
    #include <locale.h>
    #include <regex.h>
     
    int rpmatch(const char *);
        /*
        **  Возвращает 1 на ответ yes,  0 на ответ no,
        ** и -1 на иные ответы
        */
     
    main()
    {
        int  ret;
        char *resp;
     
    (void)setlocale(LC_ALL, "");
     
        do {
            /*
            ** Получить ответ на запрос да-нет.
            ** resp указывает на строку с ответом.
            ** Проверить, был ли ответ положительным.
            */
        ret = rpmatch(resp);
     
        if(ret == 1){
            /* Положительный ответ */
            /* Обработка ответа. */
            }else if(ret == 0){
            /* Отрицательный ответ. */
            /* Обработка отрицательного ответа. */
            }else if(ret<0){
            /* Другой ответ. */
            continue;
            }
        }while(ret <0);
    }
    
  10. Следующий пример иллюстрирует применение функции rpmatch. Заметим, что большинство приложений должно работать с функцией rpmatch, определенной в библиотеке libc. Код реализации rpmatch приведен здесь только для иллюстрации.

    Заметим, что для получения регулярных выражений, соответствующих утвердительному и отрицательному ответам, применяются функции nl_langinfo(YESEXPR) и nl_langinfo(NOEXPR) соответственно.

    #include <langinfo.h>
    #include <regex.h>
    /*
    ** rpmatch() сравнивает строку с регулярным выражением с помощью
    ** функций компиляции и сравнения регулярных выражений, определенных
    ** в POSIX.2. Первый аргумент - ответ пользователя, второй -
    ** текущая установка локали в виде регулярного выражения.
    */
    int rpmatch( const char *string)
    
     
     
     
    {
         int status;
         int retval;
         regex_t re;
         char *pattern;
     
         pattern = nl_langinfo(YESEXPR);
         /* Обработать регулярное выражение, на которое указывает шаблон. */
         if( ( status = regcomp( &re, pattern, REG_EXTENDED | REG_NOSUB )) != 0 ){
              retval = -2; /* -2 означает ошибку обработки положительного выражения */
              return(retval);
         }
         /* Сравнить строку с обработанным выражением. */
         status = regexec( &re, string, (size_t)0, (regmatch_t *)NULL, 0);
         if(status == 0){
              retval = 1;   /* Обнаружен положительный ответ */
         }else{    /* Поиск отрицательного ответа */
              pattern = nl_langinfo(NOEXPR);
              if( ( status = regcomp( &re, pattern,
                   REG_EXTENDED | REG_NOSUB )) != 0 ){
                        retval = -3;/* -3 означает ошибку при
                                  обработке отрицательного выражения  */
                        return(retval);
                   }
              status = regexec( &re, string, (size_t)0, 
                             (regmatch_t *)NULL, 0);
              if(status == 0)
                   retval = 0; /* Найден отрицательный ответ */
         }else
                   retval = -1; /* Не найдено ни положительного, ни
                                  отрицательного ответа */
         regfree(&re);
         return(retval);
    }
    

Связанная информация

В разделе Функции для поддержки национальных языков - Обзор приведены дополнительные сведения о функциях обработки широких и многобайтовых символов.

Общие сведения о локализации программ в разделах Глава 16, Поддержка национальных языков и Локаль - Информация для программистов.

Подробная информация по работе с локалями приведена в разделе Обзор локалей книги Руководство по управлению системой AIX 5L версии 5.1: Операционная система и устройства.

Character Set Description (charmap) source file format, Locale Definition source file format.

Сведения об отдельных категориях локали и ключевых словах можно найти в описаниях категорий LC_COLLATE, LC_CTYPE, LC_MESSAGES, LC_MONETARY, LC_NUMERIC и LC_TIME в книге AIX 5L Version 5.1 Files Reference


[ Страница назад | Страница вперед | Содержание | Индекс | Библиотека | Юридическая информация | Поиск ]