Использование Unicode в исходном коде на С++
Какова стандартная кодировка исходного кода на С++? Стандарт С++ даже говорит об этом? Могу ли я написать источник С++ в Unicode?
Например, могу ли я использовать символы, отличные от ASCII, такие как китайские символы в комментариях? Если да, то полный Unicode разрешен или просто подмножество Unicode? (например, эту 16-битную первую страницу или что-то, что она вызывала.)
Кроме того, могу ли я использовать Unicode для строк? Например:
Wstring str=L"Strange chars: â Țđ ě €€";
Ответы
Ответ 1
Кодирование на С++ довольно сложно. Вот мое понимание этого.
Каждая реализация должна поддерживать символы из базового набора символов источника. К ним относятся общие символы, перечисленные в §2.2/1 (§2.3/1 в С++ 11). Эти символы должны вписываться в один char
. Кроме того, реализации должны поддерживать способ обозначения других символов с помощью способа, называемого universal-character-names
, и выглядеть как \uffff
или \Uffffffff
и могут использоваться для обозначения символов Unicode. Подмножество из них можно использовать в идентификаторах (перечисленных в Приложении E).
Это все хорошо, но сопоставление от символов в файле, к исходным символам (используется во время компиляции) - это реализация. Это составляет используемую кодировку. Вот что он говорит буквально (версия С++ 98):
Знаки физического исходного файла сопоставлены в определенном реализацией образом, к основному символу источника set (ввод символов новой строки для индикаторов конца строки), если необходимо. Последовательности триграфа (2.3) заменяются соответствующими односимвольный внутренний представления. Любой исходный файл символ не в основном источнике набор символов (2.2) заменяется на универсальное имя-символ, воспламеняет этот символ. (An реализация может использовать любые внутренние кодирования, если фактическое расширенный символ, встречающийся в исходный файл и тот же расширенный символ, выраженный в исходном файле как универсальное имя-символ (т. используя обозначение \uXXXX), являются обрабатывается эквивалентно.)
Для gcc вы можете изменить его, используя опцию -finput-charset=charset
. Кроме того, вы можете изменить исполняемый символ, используемый для представления значений во время выполнения. Правильный вариант для этого - -fexec-charset=charset
для char (по умолчанию он равен utf-8
) и -fwide-exec-charset=charset
(по умолчанию - utf-16
или utf-32
в зависимости от размера wchar_t
).
Ответ 2
В дополнение к сообщению litb, MSVС++ поддерживает Unicode. Я понимаю, что он получает кодировку Unicode из спецификации. Он определенно поддерживает код типа int (*♫)();
или const std::set<int> ∅;
Если вы действительно впутываете код:
typedef void ‼; // Also known as \u203C
class ooɟ {
operator ‼() {}
};
Ответ 3
Стандарт С++ ничего не говорит о кодировке исходного кода, насколько я знаю.
Обычная кодировка - это 7-битный ASCII (или используемый) - некоторые компиляторы (например, Borland's) могли бы отказаться от символов ASCII, которые использовали high-bit. Там нет технической причины, по которой символы Unicode не могут использоваться, если ваш компилятор и редактор принимают их - самые современные инструменты на базе Linux и многие из лучших редакторов на базе Windows обрабатывают кодировку UTF-8 без проблем, хотя я "Не уверен, что компилятор Microsoft будет.
EDIT: похоже, что компиляторы Microsoft будут принимать файлы в кодировке Unicode, но иногда могут вызывать ошибки и в 8-разрядном ASCII:
warning C4819: The file contains a character that cannot be represented
in the current code page (932). Save the file in Unicode format to prevent
data loss.
Ответ 4
Здесь есть две проблемы. Во-первых, какие символы допускаются в коде С++ (и комментариях), например имена переменных. Во-вторых, какие символы допускаются в строках и строковых литералах.
Как отмечалось, компиляторы С++ должны поддерживать очень ограниченный набор символов на основе ASCII для символов, разрешенных в коде и комментариях. На практике этот набор символов не очень хорошо работал с некоторыми европейскими наборами символов (и особенно с некоторыми европейскими клавиатурами, в которых не было нескольких символов - например, квадратными скобками - доступно), поэтому концепция орграфов и триграфов была представил. В настоящее время многие компиляторы принимают больше, чем этот набор символов, но нет никакой гарантии.
Что касается строк и строковых литералов, С++ имеет понятие широкого символа и широкой символьной строки. Однако кодировка для этого набора символов undefined. На практике это почти всегда Unicode, но я не думаю, что здесь есть гарантия. Широкие символьные строковые литералы выглядят как L "строковый литерал", и их можно присвоить std:: wstring.
С++ 11 добавлена явная поддержка строк Unicode и строковых литералов, закодированных как UTF-8, UTF-16 большой endian, UTF-16 little endian, UTF-32 big endian и UTF-32 little endian.
Ответ 5
Для кодирования в строках я думаю, что вы должны использовать нотацию \u, например:
std::wstring str = L"\u20AC"; // Euro character
Ответ 6
Также стоит отметить, что широкие символы в С++ на самом деле не являются строками Unicode. Они всего лишь строки более крупных символов, обычно 16, но иногда 32 бита. Это определяется реализацией, хотя IIRC у вас может быть 8-разрядный wchar_t
У вас нет реальной гарантии относительно кодировки в них, поэтому, если вы пытаетесь сделать что-то вроде обработки текста, вам, вероятно, понадобится typedef для наиболее подходящий целочисленный тип для вашего юникодного объекта.
С++ 1x имеет дополнительную поддержку Unicode в виде строковых литералов UTF-8 (u8"text"
) и типов данных UTF-16 и UTF-32 (char16_t
и char32_t
IIRC), а также соответствующие строковые константы (u"text"
и u"text"
). Кодировка по символам, указанным без констант \uxxxx
или \Uxxxxxxxx
, по-прежнему определяется реализацией (и нет поддержки кодирования для сложных типов строк за пределами литералов)
Ответ 7
В этом контексте, если вы получите предупреждение C4819 от MSVС++, просто измените кодировку исходного файла на "UTF-8 с Bom".
GCC 4.1 не поддерживает это, но GCC 4.4 делает, а последняя версия Qt использует GCC 4.4, поэтому используйте "UTF-8 с Bom" в качестве кодирования исходного файла.
Ответ 8
AFAIK Он не стандартизирован, так как вы можете поместить любой тип символов в широкие строки.
Вам просто нужно проверить, что ваш компилятор настроен на исходный код Unicode, чтобы он работал правильно.