Использование Unicode в исходном коде C ++ - PullRequest
53 голосов
/ 01 декабря 2008

Какая стандартная кодировка исходного кода C ++? Стандарт C ++ вообще что-то говорит по этому поводу? Могу ли я написать исходный текст на C ++ в Unicode?

Например, могу ли я использовать не-ASCII символы, такие как китайские символы в комментариях? Если это так, разрешен ли полный Юникод или только подмножество Юникода? (например, эта 16-битная первая страница или как она там называется.)

Кроме того, можно ли использовать Unicode для строк? Например:

Wstring str=L"Strange chars: â Țđ ě €€";

Ответы [ 8 ]

34 голосов
/ 01 декабря 2008

Кодирование в C ++ довольно сложно. Вот мое понимание этого.

Каждая реализация должна поддерживать символы из базового набора символов . Они включают в себя общие символы, перечисленные в §2.2 / 1 (§2.3 / 1 в C ++ 11). Эти персонажи должны вписаться в один char. Кроме того, реализации должны поддерживать способ именования других символов, используя способ с именем universal-character-names и выглядят как \uffff или \Uffffffff и могут использоваться для ссылки на символы Юникода. Подмножество их можно использовать в идентификаторах (перечисленных в Приложении E).

Это все хорошо, но отображение символов в файле на символы источника (используется во время компиляции) определяется реализацией. Это составляет используемую кодировку. Вот что говорится буквально (версия C ++ 98):

Физические символы исходного файла отображается в определенной реализацией образом, к основному исходному персонажу set (ввод символов новой строки для индикаторов конца строки), если необходимо. Триграф последовательности (2.3) заменены соответствующими односимвольный внутренний представления. Любой исходный файл персонаж не в основном источнике набор символов (2.2) заменяется универсальное имя персонажа, которое игнорирует этот персонаж. (An реализация может использовать любой внутренний кодирование, пока фактическое расширенный символ, встречающийся в исходный файл и такой же расширенный символ, указанный в исходном файле как универсальное имя персонажа (т.е. используя обозначение \ uXXXX), обрабатывается аналогично.)

Для gcc вы можете изменить его, используя опцию -finput-charset=charset. Кроме того, вы можете изменить символ выполнения, используемый для представления значений во время выполнения. Правильным вариантом для этого является -fexec-charset=charset для символа (по умолчанию utf-8) и -fwide-exec-charset=charset (по умолчанию utf-16 или utf-32 в зависимости от размера wchar_t).

10 голосов
/ 01 декабря 2008

Насколько мне известно, стандарт C ++ ничего не говорит о кодировке файлов с исходным кодом.

Обычной кодировкой является (или имел обыкновение быть) 7-битный ASCII - некоторые компиляторы (например, Borland) отказывались от символов ASCII, которые использовали старший бит. Нет технической причины, по которой символы Unicode не могут использоваться, если ваш компилятор и редактор их принимают - большинство современных инструментов на основе Linux и многие из лучших редакторов на основе Windows обрабатывают кодировку UTF-8 без проблем, хотя я Я не уверен, что компилятор Microsoft будет.

РЕДАКТИРОВАТЬ: похоже, что компиляторы 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.
9 голосов
/ 03 декабря 2008

В дополнение к сообщению litb, MSVC ++ также поддерживает Unicode. Я понимаю, что он получает кодировку Unicode из спецификации. Это определенно поддерживает код как int (*♫)(); или const std::set<int> ∅; Если вы действительно любите запутывать код:

typedef void ‼; // Also known as \u203C
class ooɟ {
    operator ‼() {}
};
6 голосов
/ 02 декабря 2008

Здесь есть две проблемы. Во-первых, какие символы разрешены в коде C ++ (и комментариях), например имена переменных. Во-вторых, какие символы допускаются в строках и строковых литералах.

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

Что касается строк и строковых литералов, в C ++ есть концепция широких символов и строк широких символов. Однако кодировка для этого набора символов не определена. На практике это почти всегда Unicode, но я не думаю, что здесь есть какая-либо гарантия. Строковые литералы широких символов выглядят как L "строковый литерал", и их можно назначить std :: wstring's.


В C ++ 11 добавлена ​​явная поддержка строк и строковых литералов Unicode, закодированных как UTF-8, UTF-16 с прямым порядком байтов, UTF-16 с прямым порядком байтов, UTF-32 с большим порядком байтов и UTF-32 с прямым порядком байтов.

3 голосов
/ 01 декабря 2008

Для кодирования в строках, я думаю, вы должны использовать нотацию \ u , например ::

std::wstring str = L"\u20AC"; // Euro character
2 голосов
/ 23 августа 2012

В этом контексте, если вы получаете предупреждение MSVC ++ C4819, просто измените кодировку исходного файла на «UTF-8 с Bom».

GCC 4.1 не поддерживает это, но GCC 4.4 поддерживает, и в последней версии Qt используется GCC 4.4, поэтому используйте «UTF-8 with Bom» в качестве кодировки исходного файла.

2 голосов
/ 01 декабря 2008

Стоит также отметить, что широкие символы в C ++ на самом деле не являются строками Unicode как таковыми. Это просто строки больших символов, обычно 16, а иногда и 32 бит. Это определяется реализацией, хотя, IIRC у вас может быть 8-битный wchar_t У вас нет реальной гарантии в отношении кодировки в них, поэтому, если вы пытаетесь сделать что-то вроде обработки текста, вам, вероятно, понадобится typedef для наиболее подходящий целочисленный тип для вашей сущности Unicode.

C ++ 1x имеет дополнительную поддержку юникода в виде строковых литералов кодирования UTF-8 (u8"text") и типов данных UTF-16 и UTF-32 (char16_t и char32_t IIRC), а также соответствующие строковые константы (u"text" и U"text"). Однако кодировка символов, указанных без констант \uxxxx или \Uxxxxxxxx, по-прежнему определяется реализацией (и не поддерживается кодирование для сложных типов строк вне литералов)

0 голосов
/ 01 декабря 2008

AFAIK Это не стандартизировано, так как вы можете поместить любой тип символов в широкие строки. Вам просто нужно убедиться, что ваш компилятор настроен на исходный код Unicode, чтобы он работал правильно.

...