В ответ на связанный с этим вопрос я хотел бы задать вопрос о новых типах символьных и строковых литералов в 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[] = "Hello\x0A"; // byte string, "narrow encoding"
wchar_t B[] = L"Hell\xF6\x0A"; // wide string, impl-def'd encoding
char16_t C[] = u"Hell\u00F6"; // (1)
char32_t D[] = U"Hell\U000000F6\U0010FFFF"; // (2)
auto E[] = u8"\u00F6\U0010FFFF"; // (3)
Вопрос в следующем: можно ли свободно комбинировать ссылки на символы \x
/ \u
/ \U
со всеми типами строк? Все ли строковые типы имеют фиксированную ширину, то есть массивы содержат ровно столько элементов, сколько указано в литерале, или ссылки на \x
/ \u
/ \U
расширяются до переменного числа байтов? Do u""
и u8""
струны кодирующая семантику, например , я могу сказать char16_t x[] = u"\U0010FFFF"
, и не- элемент код BMP будет закодирован в последовательность utf16 два блока? И аналогично дляu8
? Могу ли я писать суррогаты-одиночки в (1) \u
? Наконец, осведомлены ли какие-либо из строковых функций о кодировании (т.е. они распознают символы и могут обнаруживать недопустимые последовательности байтов)?
Это немного открытый вопрос, но я хотел бы получить как можно более полное представление о новых возможностях кодирования UTF и типов в новом C ++ 11.
u"\U0010FFFF"
суррогатную пару.Ответы:
Номер
\x
может быть использован в чем - либо, но\u
и\U
может быть использован только в строках, которые специально UTF кодировки. Однако для любой строки в кодировке UTF\u
и\U
может использоваться по своему усмотрению.Не так, как вы имеете в виду.
\x
,\u
И\U
преобразуются на основе строки кодирования. Количество значений этих «кодовых единиц» (используя термины Unicode. Achar16_t
- кодовая единица UTF-16) зависит от кодировки содержащей строку. Литералu8"\u1024"
создаст строку, содержащую 2char
s плюс нулевой терминатор. Литералu"\u1024"
создаст строку, содержащую 1char16_t
плюс нулевой терминатор.Количество используемых кодовых единиц основано на кодировке Unicode.
u""
создает строку в кодировке UTF-16.u8""
создает строку в кодировке UTF-8. Они будут закодированы в соответствии со спецификацией Unicode.Точно нет. Спецификация прямо запрещает использование суррогатных пар UTF-16 (0xD800-0xDFFF) в качестве кодовых точек для
\u
или\U
.Точно нет. Что ж, позвольте мне перефразировать это.
std::basic_string
не работает с кодировками Unicode. Они определенно могут хранить строки в кодировке UTF. Но они могут думать только о них , как последовательностиchar
,char16_t
илиchar32_t
; они не могут думать о них как о последовательности кодовых точек Unicode, которые закодированы с помощью определенного механизма.basic_string::length()
вернет количество кодовых единиц, а не кодовых точек. И очевидно, что строковые функции стандартной библиотеки C совершенно бесполезны.Однако следует отметить, что «длина» строки Unicode не означает количество кодовых точек. Некоторые кодовые точки объединяют «символы» (неудачное имя), которые объединяются с предыдущей кодовой точкой. Таким образом, несколько кодовых точек могут отображаться на один визуальный символ.
Фактически Iostreams могут читать / записывать значения в кодировке Unicode. Для этого вам нужно будет использовать локаль, чтобы указать кодировку и правильно внедрить ее в разные места. Это легче сказать, чем сделать, и у меня нет кода, чтобы показать вам, как это сделать.
источник
\x
не может быть использована ни с чем, например , U + 1F984 не будет работать с \ х префикс, и\u
и\U
не могут быть использованы с управляющими символами ASCII, по крайней мере в Clang.