Насколько я знаю std::basic_string<wchar_t>
, где sizeof(wchar_t) == 2
не является кодировкой UTF16. В кодировке Unicode содержится более 2 ^ 16 символов, а коды имеют значение не менее 0xFFFFF
, что составляет> 0xFFFF
(емкость 2 байта wchar_t
). В результате правильный UTF16 должен использовать переменное число байтов на букву (один 2-байтовый wchar_t
или два из них), что не относится к std::basic_string
и аналогичным классам, которые предполагают, что one string element
== one character
.
Насколько я знаю, есть два способа иметь дело со строками Unicode.
- Либо используйте достаточно большой тип, чтобы поместить любой символ в один строковый элемент (например, в Linux это нормально видеть
sizeof(wchar_t) == 4
), так что вы сможете пользоваться «преимуществами» (в основном, простой длиной строки расчет и ничего больше) std::string
-подобных классов.
- Или используйте кодирование переменной длины (UTF8 - 1,4 байт на символ или UTF16 - 2,4,4 байт на символ) и хорошо протестированный класс строк, обеспечивающий процедуры манипуляции строками.
Пока вы не используете char
, не имеет значения, какой метод вы используете. * Строки на основе char
могут вызвать проблемы на машинах с другой 8-битной кодовой страницей, если вы не будете достаточно осторожны, чтобы позаботиться об этом (можно с уверенностью предположить, что вы забудете об этом и не будете достаточно осторожны - Microsoft Applocale был создан по причине).
Юникод содержит множество непечатаемых символов (управляющие и форматирующие символы в Юникоде), так что в значительной степени побеждает любой способ получения выгоды, который может предоставить # 1. В любом случае, если вы решите использовать метод № 1, вы должны помнить, что wchar_t
недостаточно велик, чтобы вместить все возможные символы на некоторых компиляторах / платформах (компилятор Windows / Microsoft), и что std::basic_string<wchar_t>
не является идеальным решением, поскольку этого.
Рендеринг интернационализированного текста - это PAIN, поэтому лучше всего было бы просто взять любой строковый класс, совместимый с юникодом (например, QString ), который, как мы надеемся, поставляется с механизмом разметки текста (который может правильно обрабатывать управляющие символы). и двунаправленный текст) и сконцентрируйтесь на более интересных задачах программирования.
-Update-
Если unsigned short не является UTF16, то что такое unsigned int? Что такое UTF8 тогда? Это беззнаковый символ?
UTF16 is переменной длины кодировка символов . UTF16 использует 1 .. 2 2-байтовые (т.е. uint16_t
, 16-битные) элементы на символ. То есть количество элементов в строке UTF16! = количество символов в строке для UTF16. Вы не можете рассчитать длину строки, считая элементы.
UTF8 - это другое кодирование переменной длины , основанное на 1-байтовых элементах (8 бит, 1 байт или "символ без знака"). Один символ Unicode («кодовая точка») в UTF8 занимает 1 .. 4 uint8_t
элементов. Еще раз, количество элементов в строке! = Количество символов в строке. Преимущество UTF8 состоит в том, что символы, существующие в ASCII, занимают ровно 1 байт на символ в UTF8, что экономит немного места, в то время как в UTF16 символ всегда занимает по крайней мере 2 байта.
UTF32 - это кодировка фиксированной длины , которая всегда использует 32-битный (4 байта или uint32_t
) на символ. В настоящее время любой символ Unicode может вписаться в один элемент UTF32, и UTF32, вероятно, будет оставаться фиксированной длины в течение длительного времени (я не думаю, что все языки Земли вместе выдали бы 2 ^ 31 различных символов). Это тратит больше памяти, но количество элементов в строке == количество символов в строке.
Кроме того, имейте в виду, что стандарт C ++ не определяет, насколько большим должно быть «int» или «short».