据我所知std::basic_string<wchar_t> 其中sizeof(wchar_t) == 2 不是UTF16 编码。 unicode 中有超过 2^16 个字符,并且代码至少达到 0xFFFFF,即 > 0xFFFF(2byte wchar_t 容量)。因此,正确的 UTF16 应该使用每个字母的可变字节数(一个 2 字节 wchar_t 或其中两个),而 std::basic_string 和假定 one string element == one character 的类似类并非如此。
据我所知,处理 unicode 字符串有两种方法。
- 要么使用足够大的类型以将任何字符放入单个字符串元素中(例如,在 linux 上看到
sizeof(wchar_t) == 4 是很正常的),因此您将能够享受“好处”(基本上,简单的字符串长度std::string-like 类的计算,仅此而已。
- 或使用可变长度编码(UTF8 - 每个字符 1..4 个字节或 UTF16 - 每个字符 2..4 个字节),以及提供字符串操作例程的经过良好测试的字符串类。
只要您不使用char,您使用哪种方法都没有关系。 char-based 字符串可能会在具有不同 8 位代码页的机器上引起问题,如果您没有足够小心地处理它(可以安全地假设您会忘记它并且不会足够小心- Microsoft Applocale 的创建是有原因的)。
Unicode 包含大量不可打印的字符(unicode 中的控制和格式化字符),因此几乎无法使用#1 可以提供的任何好处。无论如何,如果您决定使用方法#1,您应该记住wchar_t 不足以容纳某些编译器/平台(windows/microsoft 编译器)上的所有可能字符,并且std::basic_string<wchar_t> 不是一个完美的解决方案,因为那个。
渲染国际化文本是痛苦的,所以最好的办法就是抓住任何与 unicode 兼容的字符串类(如QString),希望它带有文本布局引擎(可以正确处理控制字符和双向文本)而是专注于更有趣的编程问题。
-更新-
如果 unsigned short 不是 UTF16,那么 unsigned int 是什么?那么什么是UTF8呢?那是无符号字符吗?
UTF16 是可变长度 字符编码。 UTF16 每个字符使用 1..2 2 字节(即uint16_t,16 位)元素。 IE。 UTF16 字符串中的元素数!= UTF16 字符串中的字符数。您不能通过计算元素来计算字符串长度。
UTF8 是另一种可变长度 编码,基于 1 字节元素(8 位、1 字节或“无符号字符”)。 UTF8 中的一个 unicode 字符(“代码点”)需要 1..4 uint8_t 元素。再一次,字符串中的元素数!= 字符串中的字符数。 UTF8 的优点是 ASCII 中存在的字符在 UTF8 中每个字符恰好占用 1 个字节,这样可以节省一点空间,而在 UTF16 中,字符总是至少占用 2 个字节。
UTF32 是 固定长度 字符编码,每个字符始终使用 32 位(4 字节或 uint32_t)。目前任何 unicode 字符都可以放入单个 UTF32 元素中,并且 UTF32 可能会在很长一段时间内保持固定长度(我不认为地球上的所有语言结合起来会产生 2^31 个不同的字符)。它浪费了更多的内存,但字符串中的元素数 == 字符串中的字符数。
另外,请记住,C++ 标准没有指定“int”或“short”应该有多大。