2008-12-01 7 views
44

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

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

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

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

* RE: «что бы это ни называлось»: * [Из Википедии] (https://en.wikipedia.org/wiki/Plane_%28Unicode%29#Basic_Multilingual_Plane): Первая плоскость, ** плоскость 0 **, ** Basic Multilingual Plane (BMP) ** содержит символы почти для всех современных языков и большое количество символов. Основной целью BMP является поддержка унификации предыдущих наборов символов, а также символов для записи. Большинство назначенных кодовых точек в BMP используются для кодирования ** китайских **, ** японских ** и ** корейских (CJK) ** символов. – DavidRR 2015-04-22 14:41:50

ответ

33

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

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

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

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

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

9

Стандарт C++ ничего не говорит о кодировке исходного кода, насколько я знаю.

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

EDIT: Похоже, компиляторы Microsoft будет принимать Юникоде файлы, но иногда производят ошибки на 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. 
+0

Это вроде как. Я не думаю, что он явно запрещает или разрешает unicode, но это минимально допустимый набор символов: http://www.csci.csusb.edu/dick/c++std/cd2/lex.html#lex.charset – 2008-12-01 19:45:04

+0

Начиная с C++ Builder2007, компилятор Borland/Codegear поддерживал исходные файлы Unicode: строковые литералы Unicode, комментарии в unicode. IDe немного боролся с ними, но компилятор счастлив! – Roddy 2008-12-01 20:02:02

+0

The Borland, о котором я упоминал, был примерно двадцати лет назад (последний раз, когда я пытался помещать символ высокого ASCII в файл исходного кода). :-) Я не использовал компилятор Borland примерно через десять лет. – 2008-12-01 21:20:20

3

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

std::wstring str = L"\u20AC"; // Euro character 
0

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

2

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

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

6

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

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

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


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

9

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

typedef void ‼; // Also known as \u203C 
class ooɟ { 
    operator ‼() {} 
}; 
2

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

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