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

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


Локаль - Информация для программистов

поддержка национальных языков (NLS) предоставляет набор команд и библиотечных функций, предназначенных для работы в универсальной среде. В международной системе отсутствует какая-либо зависимость от языковых особенностей или национальных стандартов. Вся информация о локали считывается во время выполнения программы.

Следующие разделы посвящены важным особенностям международных программ:

Кодовые наборы

ASCII - это кодовый набор, состоящий из 128 знаков (0x00-0x7F). В набор символов ASCII входят прописные и строчные буквы латинского алфавита, а также управляющие символы, знаки препинания и цифры. ASCII входит в качестве подмножества в некоторые 8-разрядные кодовые наборы. Однако в этом документе аббревиатура ASCII означает только 7-разрядные кодовые наборы. Если это нужно специально подчеркнуть, говорят о 7-разрядном коде ASCII. 7-разрядный кодовый набор ASCII входит во все поддерживаемые кодовые наборы и называется переносимым набором символов. Более подробная информация приведена в разделе Кодовые наборы - Обзор.

Кодовые наборы однобайтовых и многобайтовых символов

Для представления символов европейских алфавитов достаточно одного байта на символ, поскольку общее число знаков в этих алфавитах невелико. Для поддержки больших наборов символов - например, китайского и японского языка - необходимы дополнительные кодовые наборы, содержащие многобайтовые символы. Во все поддерживаемые однобайтовые и многобайтовые кодовые наборы входит набор однобайтовых символов ASCII. Следовательно, программы, работающие с многобайтовыми кодовыми наборами, должны обрабатывать также и однобайтовые коды.

Примеры кодовых наборов однобайтовых символов - это семейство кодовых наборов ISO 8859 и кодовый набор IBM-850. Примеры кодовых наборов многобайтовых символов - IBM-eucJP и IBM-943. В однобайтовый кодовый набор может входить до 256 символов; размер многобайтового кодового набора значительно больше (теоретически он неограничен).

Диапазон уникальных кодовых знаков

Ни один байт ни одного многобайтового символа в кодовом наборе не может принимать значения 0x00-0x3F. Эта группа кодовых знаков называется диапазоном уникальных кодовых знаков. Уникальные кодовые знаки всегда соответствуют символам 7-разрядного набора ASCII. Это правило соблюдается во всех поддерживаемых кодовых наборах. В разделе Символы ASCII с уникальными кодами (Символы ASCII) перечислены символы из этого диапазона.

Дополнительная информация о кодовых наборах приведена в разделе Кодовые наборы - Обзор.

Представление данных

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

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

Представление данных в виде многобайтовых символов

Многобайтовые символы - это внешнее представление данных, не зависящее от того, введен ли символ с клавиатуры или считан из файла на диске. В одном кодовом наборе различные символы могут быть представлены различным числом байт. Для обеспечения независимости работы программы от кодового набора обработку символов необходимо выполнять с помощью функций NLS.

Допустим, например, что в некотором кодовом наборе символам С и * соответствуют следующие коды:

C  = 0x43
*  = 0x81 0x43
*C = 0x81 0x43&0x43

Если программа выполняет поиск символа C, не учитывая существования многобайтовых символов, то она найдет второй байт строки *C и предположит, что найден символ C, хотя в действительности найден второй байт символа * (звездочка).

Представление данных в виде широких символов

Широкие символы разработаны для более эффективной внутренней обработки многобайтовых символов в системе. Многобайтовые символы преобразуются в единый внутренний формат (код широких символов), так что во внутреннем представлении все символы имеют одинаковую длину. Этот внутренний формат позволяет обрабатывать символы независимо от кодового набора. Такое внутреннее представление символов называется широким кодом.

Для представления кода широких символов применяется тип данных wchar_t. Размер типа данных wchar_t зависит от конкретной реализации. Этот тип определяется в операторе typedef в файлах заголовков ctype.h, stddef.h и stdlib.h. Для обеспечения переносимости программ нельзя обрабатывать данные типа wchar_t как данные какой-либо конкретной длины.

В AIX 4.3 тип данных wchar_t реализован как 16-разрядное короткое целое без знака (unsigned short). Методы работы с локалями в AIX стандартизованы, так что в большинстве локалей значение типа wchar_t, обозначающее тот или иной символ, всегда совпадает с кодом этого символа в формате Unicode. Таким образом, приложения, предназначенные для работы только на платформе AIX, могут обрабатывать значения типа wchar_t независимо от того, к какому кодовому набору они относились изначально. В AIX 4.3 широкие символы (символы в формате процесса) представлены в формате Unicode во всех локалях, кроме следующих:

  1. Локали, основанные на кодовом наборе IBM-850, сохранены исключительно для обеспечения совместимости с предыдущими версиями AIX. Эти локали остались такими же, как и в предыдущих версиях, и будут удалены в следующей версии AIX. Пользователям настоятельно рекомендуется вместо кодовых наборов IBM-850 применять промышленный стандарт ISO8859-1. Для локалей IBM-850 значения данных типа wchar_t совпадают со значениями соответствующих кодовых знаков IBM-850.
  2. В кодовый набор IBM-eucTW (LANG =zh_TW) входит много символов, отсутствующих в стандарте Unicode. Поэтому представление символов этого кодового набора широкими кодами символов Unicode невозможно. Если в приложении данные типа wchar_t для традиционного китайского языка необходимо представить в формате Unicode, следует воспользоваться локалью Zh_TW (кодовый набор big5).

Свойства символов

У каждого символа есть несколько атрибутов (свойств), зависящих от национального языка. Их называют свойствами класса. Например, строчная буква a из набора символов Английский (США) обладает следующими свойствами:

Свойства класса символов перечислены в категории LC_CTYPE.

Свойства, определяющие последовательность упорядочения

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

Для упорядочения символов любого языка по алфавиту каждому символу присваивается вес. Однако вес и кодовый знак символа не обязательно связаны между собой.

В некоторых языках для сортировки строк по алфавиту необходим дополнительный набор весов. Проиллюстрируем это на примере сравнения немецких слов b<a-умляут>ch и bane. С одним набором весов и при условии, что вес a меньше веса <a-умляут> слово bane при сортировке окажется перед словом b<a-умляут>ch. Однако в немецком языке другие правила. Поэтому в немецкой локали у каждого символа два веса: основной и дополнительный. Символы a и <a-умляут> имеют один и тот же основной вес, но разные дополнительные веса. В немецкой локали дополнительный вес символа a меньше дополнительного веса символа <a-умляут>.

Алгоритм сортировки сначала сравнивает основные веса символов двух строк. Если основные веса совпадают, сравниваются дополнительные веса. В нашем примере основные веса первых двух символов обеих строк - ba и b<a-умляут> - совпадают, но основные веса третьих символов (c и n) различны. В результате слово b<a-умляут>ch будет расположено перед bane.

В нашем примере сравнение дополнительных весов не понадобилось. Однако для таких строк, как bach и b<a-умляут>ch, при упорядочении потребуются дополнительные веса. Основные веса не позволяют различить эти две строки. В связи с этим при сравнении таких слов используются дополнительные веса символов a и <a-умляут>. Так как дополнительный вес символа a меньше дополнительного веса символа <a-умляут>, строка bach будет расположена перед строкой b<a-умляут>ch.

Символы с равными основными весами образуют класс эквивалентности. В нашем примере символы a и <a-умляут> относятся к одному классу эквивалентности.

При сортировке строк по алфавиту для каждой пары строк сначала сравниваются основные веса символов. Если различий нет, сравниваются дополнительные веса. Если и после этого различия обнаружены не будут, то будет выполнено сравнение весов третьего уровня и т.д., пока не будет достигнут предел, установленный переменной COLL_WEIGHTS_MAX в файле sys/limits.h.

Ширина кодового набора

Ширина кодового набора - это наибольшее число байтов, необходимое для представления символов этого набора в файловом формате. Этот параметр указан в категории LC_CTYPE.

Ширина кодового набора

Ширина экранного представления кодового набора - это наибольшее число колонок экрана, необходимое для представления символов набора. Этот параметр указан в категории LC_CTYPE.

Локализация

Международная программа должна правильно обрабатывать данные, представленные в различных национальных форматах. Например, в США дата в формате 9/6/1990 означает шестой день девятого месяца (шестое сентября) 1990 года. В Великобритании это же значение означает девятый день шестого месяца (девятое июня) 1990 года. Форматы чисел и валют в разных странах также различны: например, национальная валюта США - доллар, а Великобритании - фунт стерлингов.

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

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

Категории локали

Категория - это набор данных, описывающих языковые правила и национальные стандарты. Например, формат даты и времени, названия дней недели и месяцев сгруппированы в категорию LC_TIME. У каждой из категорий есть свой набор ключевых слов, описывающих конкретные особенности локали. В файле определения локали можно задать следующие стандартные категории:

LC_COLLATE Устанавливает правила сортировки строк.
LC_CTYPE Задает классификацию символов, соответствие между строчными и прописными буквами и прочие атрибуты символов.
LC_MESSAGES Определяет формат утвердительного и отрицательного ответа.
LC_MONETARY Определяет правила форматирования денежных величин и символ денежной единицы.
LC_NUMERIC Определяет правила форматирования чисел, отличных от денежных единиц.
LC_TIME Определяет правила форматирования даты и времени и соответствующие символы.

Локаль - Основные сведения

Информация локали состоит из данных, входящих в перечисленных шесть категорий. Каждая локаль описывается в файле определения локали. Имя такого файла образуется из названий языка, страны и соответствующего кодового набора. Формат имен файлов определения локали следующий:

язык[_страна][.кодовый-набор][@модификатор]

Например, файл определения локали для датского языка, на котором говорят в Дании и алфавит которого состоит из символов кодового набора ISO8859-1, называется da_DK.ISO8859-1. da означает датский язык, а DK - Данию. Краткая запись имени локали - da_DK. Локаль для того же языка и той же страны, но с кодовым набором IBM-850, называется Da_DK.IBM-850 или, сокращенно, Da_DK.

Локаль С или POSIX

Эта локаль соответствует стандарту ANSI C или POSIX для локали, наследуемой всеми процессами при запуске. В локали C или POSIX принят 7-разрядный набор символов ASCII и определены данные для всех шести перечисленных категорий.

Исходная локаль по умолчанию

Исходная локаль по умолчанию - это локаль, выбранная при установке системы в качестве общесистемной локали. Например, франкоговорящие канадцы могут выбрать по умолчанию локаль fr_CA.ISO8859-1 (fr - французский язык, CA - Канада, ISO8859-1 - название кодового набора). Исходная локаль будет использоваться всеми процессами, пока не будут изменены переменные среды NLS.

Переменные среды NLS

Для локализации в NLS применяются следующие переменные среды:

Переменные среды LC_COLLATE, LC_CTYPE, LC_MONETARY, LC_NUMERIC, LC_TIME и LC_MESSAGES определяют текущие значения для соответствующих категорий.

Переменные среды LC_ALL и LANG также определяют текущую локаль.

Переменная среды NLSPATH задает список разделенных двоеточиями имен каталогов, в которых находятся файлы каталогов сообщений. Эта переменная среды применяется компонентом Средство работы с сообщениями подсистемы NLS.

Переменная среды LOCPATH задает каталоги, в которых хранится информация для локализации, например, файлы базы данных локали, файлы методов ввода и перекодировщики iconv. В этой переменной задается список разделенных двоеточиями имен каталогов, применяемый при настройке локали для конкретного процесса.

Примечание: все программы setuid и setgid игнорируют значение переменной среды LOCPATH.

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

Приоритет Переменная среды
высокий LC_ALL
средний LC_COLLATE, LC_CTYPE, LC_MESSAGES, LC_MONETARY, LC_NUMERIC
низкий LANG

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

Приоритет переменных среды - Пример

В приведенной ниже таблице перечислены текущие значения переменных среды и описан результат вызова функции setlocale(LC_ALL,""). После вызова функции setlocale будет выбран порядок следования символов и их свойства, определенные для немецкого языка, формат валюты, определенный для США, формат даты и времени, определенный для Дании; пользовательские сообщения будут выводиться на датском языке. В последнем столбце указана локаль, устанавливаемая после вызова setlocale(LC_ALL,"").

Переменная среды и названия категорий Значения переменных среды Значение категории после вызова setlocale(LC_ALL,"")
LC_COLLATE de_DE de_DE
LC_CTYPE de_DE de_DE
LC_MONETARY en_US en_US
LC_NUMERIC (не определена) da_DK
LC_TIME (не определена) da_DK
LC_MESSAGES (не определена) da_DK
LC_ALL (не определена) (неприменима)
LANG da_DK (неприменима)

Функции обработки многобайтовых символов

Функции обработки многобайтовых символов обрабатывают символы процесса в файловом формате. Имена этих функций начинаются с префикса mb. Однако в именах некоторых функций обработки многобайтовых символов этот префикс отсутствует. Например символа mb нет в именах функций strcoll и strxfrm, хотя они обрабатывают символы процесса в многобайтовом формате. Перечисленные ниже стандартные функции языка С работают с байтами и могут применяться для обработки данных в многобайтовом формате: strcmp, strcpy, strncmp, strncpy, strcat и strncat. Стандартные функции поиска в языке С - strchr, strrchr, strpbrk, strcspn, strrchr, strspn, strstr и strtok - можно применять в следующих случаях:

Функции обработки широких символов

Функции обработки широких символов обрабатывают символы процесса в формате процесса. Как правило, имена этих функций начинаются с префикса wc. Однако из этого правила есть и исключения. Например, имена функций классификации широких символов начинаются с префикса isw. Для определения того, обрабатывает ли данная функция широкие символы, следует проверить, определены ли в прототипе этой функции символы типа wchar_t или указатели на wchar_t и возвращает ли функция значения типа wchar_t. Из этого правила также есть несколько исключений. Например, функции классификации широких символов принимают значения типа wint_t .

Двунаправленный текст и перерисовка символов

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

Двунаправленность (BIDI) реализуется при выводе текста с разной направленностью. Например, английский текст читается слева направо, а текст на иврите - справа налево. Если в одной строке содержатся фрагменты английского текста и текста на иврите, то это двунаправленный текст.

Перерисовка символов выполняется в том случае, если начертание символа зависит от его положения в строке текста. В некоторых языках, например в арабском, начертание символа зависит от его положения в строке и от соседних символов.

Более подробная информация о двунаправленном тексте и перерисовке символов приведена в разделах Начертание текста (двунаправленный текст и перерисовка символов) - Обзор, Перерисовка символов и Обзор функций библиотеки визуального представления текста.

Независимость от кодового набора

Для связи с внешней средой системе нужна определенная информация о кодовых наборах. Эта информация скрыта с помощью библиотечных функций, не зависящих от кодового набора (из библиотеки NLS). Эти функции передают информацию в функции, зависящие от кодового набора. Так как функции NLS обрабатывают необходимую информацию о кодовых наборах, для написания программ обработки символов программисту не нужно ничего знать о конкретном кодовом наборе. В программировании это называется независимостью от кодового набора.

Определение наибольшего числа байт в символах кодового набора

Для определения наибольшего числа байт в многобайтовых символах кодового набора текущей локали служит макроопределение MB_CUR_MAX. Значение макроопределения зависит от текущего значения категории LC_CTYPE. Поскольку разным процессам могут соответствовать разные локали, результаты выполнения MB_CUR_MAX в разных процессах и в разное время могут быть разными. Макроопределение MB_CUR_MAX задано в файле заголовка stdlib.h.

Для определения наибольшего числа байт в символах всех кодовых наборов, поддерживаемых в системе, служит макроопределение MB_LEN_MAX. Она задано в файле заголовка limits.h.

Определение ширины символа и строки на экране

Реализация макроопределения _max_disp_width зависит от операционной системы, поэтому ее не следует применять в переносимых приложениях. Если переносимость не важна, то с помощью _max_disp_width можно определить наибольшее число колонок на экране, необходимое для представления одного символа кодового набора текущей локали. Значение макроопределения зависит от текущего значения категории LC_CTYPE. Если значение равно 1, то все символы текущего кодового набора будут занимать одну колонку на экране.

Если значения MB_CUR_MAX и _max_disp_width равны 1, то определить число колонок на экране, необходимое для отображения строки, можно с помощью функции strlen. Если MB_CUR_MAX больше 1, то число колонок, необходимое для отображения строки, можно определить с помощью функции wcswidth.

Функций обработки многобайтовых символов, аналогичных wcswidth и wcwidth, не существует. Функция wcswidth не определяет число символов, которые можно показать на доступном участке экрана. Это число можно определить с помощью функции wcwidth. Для определения того, сколько символов можно отобразить в доступных участках экрана, необходимо повторно вызывать функцию wcswidth для строки широких символов.

Исключения из правил: Диапазон уникальных кодовых знаков

Как уже упоминалось, при написании программы разработчик должен придерживаться правила: "Программа ничего не знает о том, символы какого кодового набора она обрабатывает". Однако из этого правила есть одно исключение. Оно связано с организацией кодовых наборов, поддерживаемых в системе.

При поиске любого символа из диапазона уникальных кодовых знаков (например, точки .) в строке многобайтовых символов выполнять преобразование строки в формат кода процесса не нужно. Достаточно просто выполнить поиск соответствующего символа (.), проверяя каждый байт. Благодаря этому обстоятельству ядро и утилиты могут выполнять поиск специальных символов . и / в именах файлов. При поиске любых символов из диапазона уникальных кодовых знаков следует применять стандартные функции работы со строками, обрабатывающие байты (например, strchr). В разделе Символы ASCII перечислены символы из этого диапазона.

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

Поиск файла по имени

В стандарте POSIX.2 для поиска файлов по шаблону определена функция fnmatch. С помощью fnmatch приложение может просматривать каталог и сравнивать каждую запись с шаблоном. Например, эту функцию может применять утилита find. Утилита pax может применять функцию fnmatch для обработки операндов-шаблонов. Функция fnmatch может быть полезной в программах, в которых нужно сравнивать строки с определенным шаблоном.

Обработка символа корня

Заметим, что символ корня, возвращаемый функцией nl_langinfo(RADIXCHAR), представляет собой указатель на строку. Возможно, в какой-либо локали он будет представлен в виде многобайтового символа или строки символов. Однако в AIX для простоты символ RADIXCHAR является однобайтовым.

Модель программирования

В этом разделе описаны действия по интернационализации существующих программ и особенности разработки международных программ.

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

Глава 16, Поддержка национальных языков

Начертание текста (двунаправленный текст и перерисовка символов) - Обзор

Функции обработки многобайтовых и широких символов

Символы ASCII

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

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

Кодовые наборы - Обзор

Стратегия кодовых наборов

Character Set Description (charmap) Source File Format в книге AIX 5L Version 5.1 Files Reference

Locale Definition Source File Format в книге AIX 5L Version 5.1 Files Reference

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

Функции setlocale, strcoll и strxfrm в книге AIX 5L Version 5.1 Technical Reference: Base Operating System and Extensions Volume 2


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