Потоковая передача расширенного ASCII

Я знаю, что только положительные символьные значения ASCII гарантированы кроссплатформенной поддержкой.

В Visual Studio 2015 я могу сделать:

cout << '\xBA';

И это печатает:

Когда я примеряю это http://ideone.com Я ничего не печатаю.

Если я попытаюсь напечатать это, используя буквенный символ:

cout << '║';

Visual Studio выдает предупреждение:

предупреждение C4566: символ, представленный универсальным символьным именем ‘\ u2551’, не может быть представлен в текущей кодовой странице (1252)

А потом печатает:

?

Когда эта команда запущена на http://ideone.com Я получил:

14849425

Я прочитал это wcharЭто может обеспечить кроссплатформенный подход к этому. Это правда? Или мне просто не повезло в расширенном ASCII?

0

Решение

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

С простой строкой, компилятор может делать то, что он хочет, но он должен давать const char[], Обычно компилятор сохраняет исходную кодировку когда это может, поэтому строка, хранящаяся в вашей программе, будет иметь кодировку вашего входного файла. Бывают случаи, когда компилятор выполняет преобразование, например, если ваш файл имеет формат UTF-16 (вы не можете поместить символы UTF-16 в charс).

Когда вы используете ‘\ xBA’, вы пишете необработанный символ и выбираете себе кодировку, поэтому кодировка компилятора отсутствует.

Когда вы используете '║', тип '║' не обязательно char, Если символ не представлен в виде одного байта в наборе символов компилятора, его тип будет int, В случае Visual Studio с исходным файлом Windows-1252, '║' не подходит, поэтому будет иметь тип int и напечатан как таковой cout <<,

Вы можете принудительно кодировать префиксы для строковых литералов. u8"" заставит UTF-8, u"" UTF-16 и U"" UTF-32. Обратите внимание, что L"" префикс даст вам широкий символ wchar_t строка, но это все еще зависит от реализации. Широкие символы в Windows — это UCS-2 (2 байта на символ), но UTF-32 (4 байта на символ) в Linux.

Печать в консоль зависит только от типа переменной. cout << перегружен всеми распространенными типами, поэтому то, что он делает, зависит от типа. cout << будет обычно кормить char строки как есть для консоли (на самом деле stdin), и wcout << будет обычно кормить wchar_t Строки как есть. Другие комбинации могут иметь преобразования или интерпретации (например, кормление int). Струны UTF-8 char струны, так cout << всегда должен кормить их правильно.

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

Кодировка консоли по умолчанию в Windows — это кодовая страница 850 (не всегда так). В вашем случае ваш файл — CP 1252, а ваша консоль — CP 850, поэтому вы не можете печатать '║' напрямую (CP 1252 не содержит '║'), но вы можете использовать необработанный символ. Вы можете изменить кодировку консоли в Windows с помощью SetConsoleCP(),

В linux кодировкой по умолчанию является UTF-8, что более удобно, поскольку поддерживает весь диапазон Unicode. Ideone использует Linux, поэтому он будет использовать UTF-8. Обратите внимание, что есть добавленный слой HTTP и HTML, но они также используют UTF-8 для этого.

1

Другие решения

Здесь есть две отдельные концепции.

Первый из них является языковым стандартом, который в Microsoft-ese часто называют «кодовой страницей». Локаль определяет, какие визуальные символы представлены какой байтовой последовательностью. В вашем первом примере, в какой бы локали ваша программа ни выполнялась, она показывает символ «║» в ответ на байт 0xBA.

Другие локали или кодовые страницы будут отображать разные символы для одних и тех же байтов. Многие локали являются многобайтовыми локализацией, где для отображения одного символа может потребоваться несколько байтов. Например, в локали UTF-8 для отображения одного и того же символа display требуется три байта: 0xE2 0x95 0x91.

Второе понятие здесь — это один из набора символов исходного кода, который исходит из локали, в которой редактируется исходный код, до его компиляции. Когда вы вводите символ in в исходном коде, он может быть представлен, я полагаю, либо как символ 0xBA, либо, возможно, 0xE2 0x95 0x91, если ваш редактор использует локаль UTF-8. Компилятор, когда он читает исходный код, просто видит фактическую последовательность байтов. Все уменьшается до байтов.

К счастью, все ключевые слова C ++ используют US-ASCII, поэтому не имеет значения, какой набор символов используется для написания кода C ++. Пока вы не начнете использовать нелатинские символы. В результате выдается предупреждение компилятора, информирующее вас в основном о том, что вы используете то, что может работать, а может и не работать, в зависимости от конечной локали, в которой работает результирующая программа.

1

По вопросам рекламы [email protected]