Кодировка 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 ссылки расширяются в переменное число байтов? Делай u"" и u8"" строки имеют семантику кодирования, например, могу ли я сказать char16_t x[] = u"U0010FFFF", а не БМП кода будет закодирован в два-блок последовательность формате UTF16? И точно так же для u8? В (1), могу ли я написать одинокие суррогаты с u? Наконец, являются ли какие-либо из строковых функций кодирования осведомленными (т. е. они являются символьными и могут обнаруживать недопустимый байт последовательности)?

это немного открытый вопрос, но я хотел бы получить как можно более полную картину новых объектов UTF-кодирования и типа нового C++11.

1 73

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; они не могут думать о них как о последовательности кодовых точек Юникода, которые кодируются с помощью определенного механизма. basic_string::length() возвращает количество единиц кода, а не код. И, очевидно, строковые функции стандартной библиотеки C совершенно бесполезны

однако следует отметить ,что "длина" для Unicode строка не означает количество кодовых точек. Некоторые кодовые точки объединяют "символы" (неудачное имя), которые объединяются с предыдущей кодовой точкой. Таким образом, несколько кодовых точек могут сопоставляться с одним визуальным символом.

Iostreams может фактически читать / записывать значения в кодировке Unicode. Для этого вам нужно будет использовать локаль, чтобы указать кодировку и правильно наполнить ее в разных местах. Это легче сказать, чем сделать, и у меня нет никакого кода, чтобы показать вам, как это сделать.