Кодировка Unicode для строковых литералов в C++11
после вопрос, я хотел бы спросить о новых типах символьных и строковых литералов в C++11. Похоже, что теперь у нас есть четыре вида символов и пять видов строковых литералов. Типы символов:
char a = 'x30'; // character, no semantics
wchar_t b = L'xFFEF'; // wide character, no semantics
char16_t c = u'u00F6'; // 16-bit, assumed UTF16?
char32_t d = U'U0010FFFF'; // 32-bit, assumed UCS-4
и строковые литералы:
char A[] = "Hellox0A"; // byte string, "narrow encoding"
wchar_t B[] = L"HellxF6x0A"; // wide string, impl-def'd encoding
char16_t C[] = u"Hellu00F6"; // (1)
char32_t D[] = U"HellU000000F6U0010FFFF"; // (2)
auto E[] = u8"u00F6U0010FFFF"; // (3)
вопрос вот в чем: являются ли x
/u
/U
ссылки на символы свободно сочетаются со всеми строковыми типами? Являются ли все типы строк фиксированной шириной, т. е. массивами содержит ровно столько элементов, сколько появляется в литерале, или до x
/u
/U
ссылки расширяются в переменное количество байтов? Do u""
и u8""
строки имеют семантику кодирования, например, могу ли я сказать char16_t x[] = u"U0010FFFF"
, и кодовая точка без BMP кодируется в двухблочную последовательность UTF16? И аналогично для u8
? В (1), могу ли я написать одинокие суррогаты с u
? Наконец, известны ли какие-либо из строковых функций кодирования (т. е. они знакомы с символами и могут обнаруживать недопустимые последовательности байтов)?
это немного открытый вопрос, но я хотел бы получить как можно более полную картину новых средств кодирования и типа UTF нового C++11.
1 ответов
являются ли ссылки на символы \x/\u/\U свободно комбинируемыми со всеми строковыми типами?
нет. \x
можно использовать в чем угодно, но \u
и \U
может использоваться только в строках, которые специально кодируются UTF. Однако, для любой кодировке UTF-кодировке, \u
и \U
может использоваться по вашему усмотрению.
все типы строк фиксированной ширины, т. е. массивы содержат ровно столько элементов, сколько отображается в литерале, или \X/\u / \ u ссылки расширяются в переменное количество байтов?
не в этом смысле. \x
, \u
и \U
преобразуются на основе кодировки. Количество этих "кодовых единиц" (с использованием терминов Unicode. А char16_t
является кодовой единицей UTF-16) значения зависят от кодировки содержащей строки. Буквальное u8"\u1024"
создаст строку, содержащую 2 char
s плюс нулевой Терминатор. Буквальное u"\u1024"
создать строку, содержащую 1 char16_t
плюс нуль-Терминатор.
количество используемых кодовых единиц основано на кодировке Unicode.
строки u"" и u8 ""имеют семантику кодирования, например, могу ли я сказать char16_t x[] = u"\U0010FFFF", и кодовая точка, отличная от BMP, кодируется в двухблочную последовательность UTF16?
u""
создает строку в кодировке UTF-16. u8""
создает строку в кодировке UTF-8. Они будут кодироваться в соответствии со спецификацией Unicode.
в (1), могу ли я написать одинокие суррогаты с \u?
абсолютно нет. Спецификация явно запрещает использование суррогатных пар UTF-16 (0xD800-0xDFFF) в качестве кодовых точек для \u
или \U
.
наконец, известны ли какие-либо из строковых функций кодирования (т. е. они знакомы с символами и могут обнаруживать недопустимые последовательности байтов)?
абсолютно нет. Позвольте мне перефразировать.
std::basic_string
не работа с кодировками Unicode. Они, конечно, могут магазине строки в кодировке UTF. Но они могут думать о них только как о последовательностях char
, char16_t
или char32_t
; они не могут думать о них как о последовательности кодовых точек Unicode, которые кодируются с помощью определенного механизма. basic_string::length()
возвращает количество кодовых единиц, а не кодовых точек. И, очевидно, строковые функции стандартной библиотеки C абсолютно бесполезны
следует отметить, однако, что "длина" для Юникода string не означает количество кодовых точек. Некоторые кодовые точки объединяют "символы" (неудачное имя), которые объединяются с предыдущей кодовой точкой. Таким образом, несколько кодовых точек могут сопоставляться с одним визуальным символом.
Iostreams может фактически читать / записывать значения, закодированные в Юникоде. Для этого вам нужно будет использовать локаль, чтобы указать кодировку и правильно внедрить ее в различные места. Это легче сказать, чем сделать, и у меня нет никакого кода, чтобы показать вам, как.