Правила данного языка определяют использование набора символов. В частности, правила влияют на сортировку символов. Например, на французском е, é и è все должны находиться между d и f, независимо от назначенных этим символам числовых значений. Различные языки могут назначить (и назначают) одним и тем же глифам различный порядок сортировки.

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

<p>13.4.1. Широкие символы</p>

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

Широкие символы представлены на С типом wchar_t. C99 предоставляет соответствующий тип wint_t, в котором может находиться любое значение, допустимое для wchar_t, а также специальное значение WEOF, аналогичное обычному EOF из . В заголовочном файле > определены различные типы. Ряд функций, сходных с функциями в , такие, как iswalnum() и др., определены в заголовочном файле .

Широкие символы могут быть от 16 до 32 битов размером в зависимости от реализации. Как упоминалось, они нацелены на манипулирование данными в памяти и обычно не хранятся в файлах непосредственно.

Стандарт C предусматривает для широких символов большое число функций и макросов, соответствующих традиционным функциям, работающим с данными char. Например, wprintf(), iswlower() и т.д. Они документированы в справочных страницах GNU/Linux и в книгах по стандартному С.

<p>13.4.2. Представления многобайтных символов</p>

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

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

Значительным преимуществом Unicode является то, что его представления являются самокорректирующимися; кодировки не используют состояния регистров, поэтому потеря данных в середине не может повредить последующим закодированным данным.

Первоначальные версии функций преобразования многобайтных символов в широкие и широких в многобайтные поддерживали закрытую копию состояния преобразования (например, состояние регистра, а также все остальное, что могло понадобиться) Такая модель ограничивает использование функции лишь одним видом преобразования в течение жизни программы. Примерами являются mblen() (определение длины многобайтной строки), mbtowc() (преобразование многобайтного символа в широкий), wctomb() (преобразование широкого символа в многобайтный), mbstowcs() (преобразование многобайтной строки в строку широких символов), wcstombs() (преобразование строки широких символов в многобайтную строку).

Новые версии этих процедур называются повторно запускаемыми (restartable). Это означает, что код уровня пользователя сохраняет состояние преобразования в отдельном объекте типа mbstate_t. Соответствующими примерами являются mbrlen(), mbrtowc(), wcrtomb(), mbsrtowcs() и wcsrtombs(). (Обратите внимание на r в их именах, это означает «restartable».)

<p>13.4.3. Языки</p>

Языковые проблемы управляются локалью. Ранее в главе мы уже видели setlocale() POSIX предоставляет продуманный механизм для определения правил, посредством которых работает локаль; некоторые подробности см. в справочной странице GNU/Linux locale(5), а полностью — в самом стандарте POSIX.

Перейти на страницу:

Похожие книги