Подтвердить что ты не робот

Кодировка Unicode для строковых литералов в С++ 11

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

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

4b9b3361

Ответ 1

Являются ли ссылки символов \x/\ u/\ U свободно комбинируемыми со всеми типами строк?

Нет. \x может использоваться во всех случаях, но \u и \u могут использоваться только в строках, которые специфически кодируются в UTF. Однако для любой строки, кодированной в UTF, \u и \u могут использоваться по вашему усмотрению.

Являются ли все типы строк фиксированной шириной, т.е. массивы содержат точно столько же элементов, сколько и в литеральном, или для ссылок \x/\ u/\ U расширяются в число переменных байтов?

Не так, как вы. \x, \u и \u преобразуются на основе строковой кодировки. Число этих "кодовых блоков" (с использованием условий Unicode. A char16_t - это код кода UTF-16), зависит от кодировки содержащейся строки. Литерал u8"\u1024" создал бы строку, содержащую 2 char плюс нулевой ограничитель. Литерал 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 абсолютно бесполезны

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

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