Обычно при работе с консолью люди сразу же замечают такую вещь: страница по-умолчанию ANSI (ACP) не совпадает с кодовой страницей OEM (OEMCP) для большинства локалей.
Это идёт из времён MS-DOS (как и многие другие вещи!)...
Когда у нас было время DOS, кодовые страницы контролировались IBM, а не Microsoft. Многие "оригинальные" кодовые страницы появились в это время - от интересных до очень странных (да, я говорю о кодовой странице №437!), хотя некоторые из них предшествуют даже IBM (насчёт этого я точно не уверен).
Затем вышла Windows с кодовыми страницами Windows, разработанными (если можно так сказать о данных), чтобы обрабатывать много языков одновременно. Смоделированными по серии ISO-8859, но с добавлением символов, полезных большинству языков, а не выбранным (типа базовой поддержки французского в арабской кодовой странице):
- 1250 - Central Europe
- 1251 - Cyrillic
- 1252 - Latin 1 (иногда называемая Western European)
- 1253 - Greek
- 1254 - Turkish
- 1255 - Hebrew
- 1256 - Arabic
- 1257 - Baltic
- 1258 - Vietnam
Итак, эти кодовые страницы не равны по соображениям совместимости.
- Ага - скажете вы, - но почему же тогда ACP и OEMCP равны для всех локалей CJK? У нас есть:
- 932 - Japanese (Shift-JIS)
- 936 - Simplified Chinese (GBK)
- 949 - Korean
- 950 - Traditional Chinese (Big5)
Для этого есть много причин. Одна из самых очевидных - эти четыре кодовые страницы изначально создавались по стандартам (государственным или промышленным) и поэтому у них нет вопроса обратной совместимости. Никто не захотел просто так штамповать кодовые страницы.
Одна из архитектурных причин, которые влияют на NT - правила о кодовых страницах в режиме ядра. У функции API типа RtlUnicodeStringToOemString и RtlUnicodeStringToAnsiString есть неявное предположение, что размер строки при конвертации никогда не изменится (т.е. при конвертации ANSI <-> OEM размер строки в байтах меняться не может). И для кодовых страниц не-CJK это не проблема: потому что либо символ находится в кодовой странице и занимает один байт, либо его там нет и он представлен вопросительным знаком (который тоже занимает один байт). Но кодовые страницы CJK могут иметь символы длиной в несколько байт. Поэтому будет плохой идеей заводить разные (для ANSI/OEM) кодовые страницы, одна из которых кодирует символ в один байт, а другая - в несколько.
(Эти функции также предполагают, что размер любого Unicode-символа равен двум байтам - что действительно так для символов из любых кодовых страниц ANSI и OEM. И для тех, кому интересно: функции в ntdll.dll не ставят вопрос об обработке precomposed или composite Unicode - они поддерживают только форму precomposed. И Джулия не несёт за эти функции никакой ответственности, хотя она когда-то исправляла в них баги!)
В любом случае, кодовые страницы восточной Азии избавлены от необходимости в двух кодовых страницах. Это хорошо, потому что у них есть и другие вещи, о которых нужно волноваться - функции типа IsDBCSLeadByte...
Ну, разве вы не рады, что вы используете Unicode и вам не нужно волноваться об этих проблемах? :-)
1 - и даже не заикайтесь о системе наименования, в которой у одного акронима (API) не все буквы заглавные, а в других (ANSI, OEM) - все. Боже...
This post brought to you by "ì" (U+00ec, a.k.a. LATIN SMALL LETTER I WITH GRAVE)
Комментариев нет:
Отправить комментарий
Можно использовать некоторые HTML-теги, например:
<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>
Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку.
Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.
Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.
Примечание. Отправлять комментарии могут только участники этого блога.