Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
kernigan_paik.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
2.91 Mб
Скачать

8.8. Интернационализация

Если вы живете в Соединенных Штатах, то вы, может быть, забыли, что английский — не единственный язык на свете, ASCII — не единствен­ный набор символов, $ — не единственный символ валюты, что даты мо­гут записываться с указанием сначала дня, а потом уже месяца, что время может записываться в формате с 24-мя часами и т. п. Так вот, еще один аспект переносимости в общем виде связан с созданием программ, пере­носимых между разными языками и культурными границами. Это на са­мом деле весьма обширная тема для разговора, и мы будем вынуждены ограничиться освещением лишь нескольких основных концепций.

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

Не рассчитывайте на ASCII. В большинстве стран мира наборы симво­лов богаче, чем ASCII. Стандартная функция проверки символов из ctype.h, в общем, успешно справляется с этими различиями:

if (isalpha(c)) ...

Такое выражение не зависит от конкретной кодировки символов, а глав­ное — если программу скомпилировать в локальной среде, то она будет работать корректно и в тех случаях, когда букв больше или меньше, чем от а до z. Правда, имя isalpha ("это буква?") говорит само за себя, а ведь существуют языки, в которых алфавита нет вообще.

В большинстве европейских стран кодировка ASCII, определяющая только значения до 0x7F (7 битов), расширяется дополнительными сим­волами, которые представляют собой буквы национальных языков.

Кодировка Latin-1, широко распространенная в Западной Европе, явля­ется расширением ASCII, определяющим значения байтов от 80 до FF для небуквенных символов и акцентированных букв — так, значение Е7 представляет букву д. Английское слово boy представляется в ASCII (или Latin-1) тремя байтами с шестнадцатеричными значениями 62 6F 79, а французское слово gargon представляется в Latin-1 байтами 67 61 72 Е7 6F 6Е. В других языках определяются, соответственно, другие символы, но они не могут уложиться в 128 значений, не используемых в ASCII, так что существует множество конфликтующих стандартов для симво­лов, привязанных к байтам от 80 до FF.

Некоторым языкам вообще не хватает 8 битов: в большинстве азиат­ских языков существуют тысячи символов. В кодировках, используе­мых в Китае, Японии и Корее, на символ отводится 16 битов. В результа­те возникает глобальная проблема переносимости: как прочитать документ на некотором языке на компьютере, настроенном на другой язык. Даже если все символы передадутся без ошибок, для прочтения на американском компьютере документа на китайском языке должны как минимум стоять специальные шрифты и соответствующее программное обеспечение. Если же мы захотим на одной машине использовать анг­лийский, китайский и русский языки, проблем у нас возникнет море.

Набор символов Unicode — попытка улучшить описанную ситуацию, предоставив единую кодировку для всех языков мира. Unicode совмес­тима с 16-битовым подмножеством стандарта ISO 10646; в ней исполь­зуется 16 битов на символ. Значения от 00FF и ниже относятся к Latin-1, то есть слово gargon будет представлено 16-битовыми значениями 0067 0061 0072 00Е7 006F 006Е. Кириллица занимает значения от 0401 до 04FF, а идеографическим языкам отведен большой блок, начинающийся с 3000. Все известные и некоторые почти неизвестные языки мира пред­ставлены в Unicode, так что именно этой кодировкой и стоит пользовать­ся для передачи документов между странами или для хранения текста, написанного на разных языках. Unicode стала весьма популярна в Интер­нете, и некоторые языки программирования даже поддерживают ее как стандартный формат: например, Java использует Unicode как родной на­бор символов для строк. Операционные системы Plan 9 и Inferno исполь­зуют Unicode более широко — даже для имен файлов и пользователей. Microsoft Windows поддерживает набор символов Unicode, но не считает его стандартом; большинство приложений Windows до сих пор лучше работает с ASCII, хотя соотношение стремительно меняется в пользу Unicode.

Надо сказать, что и у Unicode есть недостатки: символы в ней уже не умещаются в один байт, поэтому текст в Unicode страдает от проблемы порядка байтов. Для преодоления этой напасти документы в Unicode перед передачей между программами или по сети обычно преобразуют­ся в кодировку потока байтов, называемую UTF-8. В ней каждый 16-би­товый символ кодируется для передачи как последовательность из 1, 2 или 3 байтов. Набор символов ASCII использует значения от 00 до 7F, все они умещаются в один байт при использовании UTF-8. Таким об­разом, получается, что UTF-8 односторонне совместима с ASCII. .'Зна­чения между 80 и 7FF представляются двумя байтами, а значения от 800 и выше — тремя.14 В UTF-8 слово gargon представляется байтами 67 61 72 СЗ А7 6F 6Е; значение Unicode E7 —символ g — представляется в UTF-8 двумя байтами — СЗ А7.

Совместимость UTF-8 с ASCII весьма полезна, поскольку благодаря ей программы, рассматривающие текст как непрерывный поток байтов, могут работать с текстом Unicode на любом языке. Мы опробовали про­грамму markov из третьей главы с текстом в UTF-8 на русском, грече­ском, японском и китайском языках, и она работала без каких-либо про­блем. Для европейских языков, слова в которых разделяются ASCI -сим­волами пробелов, табуляции или перевода строки, программа выдавала вполне сносный текст. При использовании других языков для того, что­бы получить что-то приемлемое на выходе, пришлось бы изменять пра­вила разбиения текста на слова.

С и C++ поддерживают "широкие символы" (wide characters), кото­рые представляются 16-битовыми или еще большими целыми. Суще­ствуют и соответствующие функции, которые могут быть использованы для обработки символов в Unicode или в другом расширенном наборе символов. Строковые константы из широких символов записываются как L". . .". Однако и здесь возникает большая проблема с переносимос­тью: программа с константами из широких символов может быть вос­произведена только на дисплее, использующем тот же набор символов. Поскольку символы должны быть конвертированы в поток байтов вроде UTF-8 для передачи между машинами, язык С предоставляет функции для преобразования широких символов в байты и обратно. Однако какое преобразование использовать? Интерпретация набора символов и опи­сания кодировки потока байтов таятся в недрах библиотек, и вытащить их оттуда достаточно сложно; ситуация складывается не в нашу пользу. Может статься, в отдаленном светлом будущем все наконец придут к согласию об использовании единого набора символов, но пока что от проблемы порядка байтов никуда нам не деться.

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

Как же быть с сообщениями об ошибках? По крайней мере, в них не должно использоваться жаргона или сленга; лучше всего писать на самом простом языке. Полезно еще собрать тексты всех сообщений в каком-то одном месте программы — тогда можно будет быстро перевести их все.

Существует множество местных культурных особенностей, например формат дат mm/dd/yy используется только в Северной Америке. Если су­ществует вероятность того, что ваша программа будет использоваться в другой стране, от таких особенностей надо по возможности избавить­ся. Иконки в графическом интерфейсе очень часто зависят от традиций; если понятия, на которых базируется зрительный образ, пользователю незнакомы, такая иконка его только дезориентирует.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]