Какая стандартная кодировка исходного кода C++? Говорит ли что-нибудь об этом в стандарте C++? Могу ли я написать исходный код C++ в Юникоде?
Например, могу ли я использовать в комментариях символы, отличные от ASCII, например китайские символы? Если да, то разрешен ли полный Юникод или только его подмножество? (например, эта 16-битная первая страница или как там она называется.)
Кроме того, могу ли я использовать Unicode для строк? Например:
Wstring str=L"Strange chars: â Țđ ě €€";
У меня был интересный вариант. У меня был символ UTF-8 µ, показанный как µ в моих журналах. Я подозревал, что GNU g ++ принял исходный код iso-8859-1 и закодировал односимвольную двухбайтовую последовательность в двоичном файле. На самом деле он понял, что источник был UTF-8 на основе локали. Журнал содержит правильную двухбайтовую последовательность. Дело в том, что другая часть журнала содержала случайные байты, которые вводили в файл байтовые последовательности, не соответствующие UTF-8. Итак, редактор emacs определил, что файл, безусловно, был ISO-8859-1, и показал двухбайтовые символы как два отдельных символа. Исправление этих случайных байтов устранило проблему.





Насколько мне известно, стандарт 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.
Это вроде как. Я не думаю, что это явно запрещает или разрешает Unicode, но это минимально допустимый набор символов: csci.csusb.edu/dick/c++std/cd2/lex.html#lex.charset
Начиная с C++ Builder2007, компилятор Borland / Codegear поддерживает исходные файлы Unicode: то есть строковые литералы Unicode, комментарии Unicode. IDe немного боролась с ними, но компилятор доволен!
Упомянутая мною вещь с Borland возникла примерно двадцать лет назад (в последний раз я пытался поместить символ высокого ASCII в файл исходного кода). :-) Я не использовал компилятор Borland около десяти лет.
Компиляторы Microsoft поддерживают Unicode только для широких символов (L "...").
Для кодирования в строках, я думаю, вы должны использовать нотацию \ u, например:
std::wstring str = L"\u20AC"; // Euro character
AFAIK Это не стандартизовано, так как вы можете помещать символы любого типа в широкие строки. Вам просто нужно убедиться, что ваш компилятор настроен на исходный код Unicode, чтобы он работал правильно.
Кодирование в C++ довольно сложно. Вот мое понимание этого.
Каждая реализация должна поддерживать символы из базовый исходный набор символов. К ним относятся общие символы, перечисленные в §2.2 / 1 (§2.3 / 1 в C++ 11). Все эти символы должны уместиться в один char. Кроме того, реализации должны поддерживать способ именования других символов, используя способ, называемый universal-character-names, и выглядящий как \uffff или \Uffffffff, и может использоваться для ссылки на символы Unicode. Некоторые из них могут использоваться в идентификаторах (перечислены в Приложении E).
Все это хорошо, но отображение символов в файле на исходные символы (используемые во время компиляции) определяется реализацией. Это составляет используемую кодировку. Вот что написано буквально (версия C++ 98):
Physical source file characters are mapped, in an implementation-defined manner, to the basic source character set (introducing new-line characters for end-of-line indicators) if necessary. Trigraph sequences (2.3) are replaced by corresponding single-character internal representations. Any source file character not in the basic source character set (2.2) is replaced by the universal-character-name that des- ignates that character. (An implementation may use any internal encoding, so long as an actual extended character encountered in the source file, and the same extended character expressed in the source file as a universal-character-name (i.e. using the \uXXXX notation), are handled equivalently.)
Для gcc вы можете изменить его, используя опцию -finput-charset=charset. Кроме того, вы можете изменить символ выполнения, используемый для представления значений во время выполнения. Подходящим вариантом для этого является -fexec-charset=charset для char (по умолчанию это utf-8) и -fwide-exec-charset=charset (по умолчанию либо utf-16, либо utf-32, в зависимости от размера wchar_t).
Также стоит отметить, что широкие символы в 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, по-прежнему определяется реализацией (и нет поддержки кодирования для сложных строковых типов вне литералов)
Разве строчная буква u не предназначена только для символов?
Здесь есть две проблемы. Во-первых, какие символы разрешены в коде C++ (и комментариях), например, имена переменных. Второй - какие символы разрешены в строках и строковых литералах.
Как уже отмечалось, компиляторы C++ должен поддерживают очень ограниченный набор символов на основе ASCII для символов, разрешенных в коде и комментариях. На практике этот набор символов не очень хорошо работал с некоторыми европейскими наборами символов (и особенно с некоторыми европейскими клавиатурами, на которых не было нескольких символов, таких как квадратные скобки), поэтому концепция орграфов и триграфов была введен. Многие компиляторы в настоящее время принимают больше, чем этот набор символов, но нет никаких гарантий.
Что касается строк и строковых литералов, в C++ есть концепция строки широких символов и строки широких символов. Однако кодировка для этого набора символов не определена. На практике это почти всегда Unicode, но я не думаю, что здесь есть какие-либо гарантии. Строковые литералы с широкими символами выглядят как L «строковый литерал», и их можно присвоить std :: wstring.
В C++ 11 добавлена явная поддержка строк Unicode и строковых литералов, закодированных как UTF-8, UTF-16 с прямым порядком байтов, UTF-16 с прямым порядком байтов, UTF-32 с прямым порядком байтов и UTF-32 с прямым порядком байтов.
Помимо сообщения litb, MSVC++ также поддерживает Unicode. Я так понимаю, он получает кодировку Unicode из спецификации. Он определенно поддерживает такие коды, как int (*♫)(); или const std::set<int> ∅;.
Если вам действительно нравится обфускация кода:
typedef void ‼; // Also known as \u203C
class ooɟ {
operator ‼() {}
};
Это может быть полезно для написания, например, математического программного обеспечения, в котором исходный код может быть согласован с исходным материалом. Вы можете сделать это в Java, которая принимает исходный код UTF-8. Однако для C++ (и C) могут возникнуть проблемы с преобразованием токенов, отличных от ASCII, в имена символов, которые должны быть совместимы с остальной частью операционной системы, а не только функцией компилятора. Для C++ это можно отнести к искажению имен.
В этом контексте, если вы получаете предупреждение MSVC++ C4819, просто измените кодировку исходного файла на «UTF-8 with Bom».
GCC 4.1 не поддерживает это, но GCC 4.4 поддерживает, а последняя версия Qt использует GCC 4.4, поэтому используйте "UTF-8 with Bom" в качестве кодировки исходного файла.