Windows консольное окно - это чистый Unicode. В его буфере хранится текст в формате UCS-2 Unicode (16 бит на символ, по сути, как в оригинальном Unicode, ограничение на базовую многоязычную плоскость современного 21-разрядного Unicode). Таким образом, окно консоли может отображать практически все виды текста.
Однако для одного байта на символ (и, возможно, также для некоторых кодировок переменной длины) Windows автоматически переводит в / из активную кодовую страницу консольного окна . Если окно консоли является экземпляром [cmd.exe], вы можете проверить это с помощью команды chcp
, сокращенно change code page . Как это:
C:\test> chcp
Active code page: 850
C:\test> _
Кодовая страница 850 - это кодировка, основанная на исходной кодовой странице 437 IBM PC на английском языке. 850 - это значение по умолчанию для консольных окон по крайней мере на норвежских ПК (хотя опытные норвежцы могут изменить это значение на 865). Однако ни одна из этих кодовых страниц не должна использоваться.
Исходная кодовая страница IBM PC (кодировка символов) известна как OEM , что является бессмысленной аббревиатурой, Производитель оригинального оборудования . У него были хорошие символы рисования линий, подходящие для экрана текстового режима оригинального ПК. В более общем смысле OEM означает кодовую страницу по умолчанию для консольных окон , где кодовая страница 437 является только исходной: ее можно настроить, например, за окно через chcp
.
Когда Microsoft создала 16-битную Windows, они выбрали другую кодировку, известную в Windows как ANSI . Первоначально это было расширение ISO Latin-1 , которое долгое время было по умолчанию в Интернете (однако, неясно, что было первым: Microsoft участвовала в стандартизации). Этот оригинальный ANSI теперь известен как Windows ANSI Western .
ANSI - это кодовая страница, используемая не для Unicode почти во всех остальных Windows. Консольные окна используют OEM. Блокнот, другие редакторы и т. Д. Используйте ANSI.
Затем, когда Microsoft сделала Windows 32-разрядной, они приняли 16-разрядное расширение Latin-1, известное как Unicode . Microsoft была первоначальным членом-учредителем Unicode Consortium. А базовый API, включая консольные окна, файловую систему и т. Д., Был переписан для использования Unicode. Для обратной совместимости существует слой перевода, который переводит между OEM и Unicode для консольных окон, и между ANSI и Unicode для других функций. Например, MessageBoxA
- это оболочка ANSI для Unicode MessageBoxW
.
Практическим результатом этого является то, что в Windows ваш исходный код C ++ обычно кодируется с помощью ANSI, в то время как консольные окна предполагают OEM. Который, например делает
cout << "I like Norwegian blåbærsyltetøy!" << endl;
производит чистую тряпку и ад; Вы можете использовать API-интерфейсы консольных окон на основе Unicode для вывода Unicode напрямую в консольное окно, избегая перевода, но это неудобно.
Обратите внимание, что использование wcout
вместо cout
не помогает: по конструкции wcout
просто переводит вниз из широких строк символов в узкий набор символов программы, отбрасывая информацию о пути. Трудно поверить, что стандартная библиотека C ++ предлагает довольно большой кусок очень очень сложной функциональности, которая не имеет смысла (поскольку вместо этого эти преобразования могли бы просто поддерживаться cout
). Но так оно и есть, просто бессмысленно. Возможно, это был какой-то политический компромисс, но, в любом случае, wcout
не помогает, даже если бы он имел какое-то значение, тогда он "должен" логически помочь с этим.
Так, как норвежский начинающий программист получает, например, "blåbærsyltetøy" представлены?
Ну, просто изменив активную кодовую страницу на ANSI. Поскольку на большинстве ПК стран Западной Европы ANSI является кодовой страницей 1252, вы можете сделать это для данного экземпляра интерпретатора команд с помощью
C:\test> chcp 1252
Active code page: 1252
C:\test> _
Теперь старые программы для DOS, такие как, например, [edit.com] (все еще присутствует в Windows XP!) создаст некоторую заглушку, потому что исходные символы рисования набора символов ПК отсутствуют в ANSI, а национальные символы имеют разные коды в ANSI. Но кто использует старые программы для DOS? Не я!
Если вы хотите, чтобы это была более постоянная кодовая страница, вам придется изменить конфигурацию консольных окон с помощью недокументированного ключа реестра:
HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Control \ NLS \ CodePage
В этом ключе измените значение OEMCP
на 1252 и перезагрузите .
Как и в случае с chcp
, или другим изменением кодовой страницы на 1252, старые DOS-программы могут показаться излишним, но программы на C ++ или другие современные консольные программы работают нормально.
Так как в консольных окнах используется та же кодировка символов, что и в остальных Windows.