Использование 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, чтобы он работал правильно.