字符串类实现的差异

Differences in string class implementations

本文关键字:实现 字符串      更新时间:2023-10-16

为什么字符串类以几种不同的方式实现,优点和缺点是什么?我看过好几种不同的做法

  1. 仅使用简单的char(最基本的方式)。
  2. 支持UTF8和UTF16格式的模板字符串,如string<UTF8>。其中UTF8char, UTF16unsigned short
  3. 字符串类中同时有UTF8和UTF16。

是否有其他更好的方法来实现字符串类?

据我所知std::basic_string<wchar_t>其中sizeof(wchar_t) == 2不是UTF16编码。unicode中有超过2^16个字符,并且代码至少到0xFFFFF> 0xFFFF (2byte wchar_t容量)。因此,适当的UTF16应该使用可变字节数的每个字母(一个2byte的wchar_t或两个),这不是std::basic_string和类似的类的情况下,假设one string element == one character

据我所知,有两种方法可以处理unicode字符串。

  1. 要么使用足够大的类型来适应任何字符到单个字符串元素(例如,在linux上看到sizeof(wchar_t) == 4是很正常的),所以你将能够享受std::string类的"好处"(基本上,简单的字符串长度计算,没有别的)。
  2. 或者使用变长编码(UTF8 - 1..)每个字符4字节或UTF16 - 2..每个字符4个字节),以及经过良好测试的字符串类,它提供了字符串操作例程。

只要你不使用char,你使用哪种方法都没关系。基于char的字符串可能会在具有不同8位代码页的机器上造成麻烦,如果你不够小心的话(可以肯定的是,你会忘记它,不会足够小心——微软Applocale的创建是有原因的)。

Unicode包含大量不可打印的字符(Unicode中的控制和格式化字符),因此几乎抵消了方法#1所能提供的任何好处。无论如何,如果你决定使用方法#1,你应该记住,wchar_t不够大,无法适应某些编译器/平台(windows/microsoft编译器)上所有可能的字符,因此std::basic_string<wchar_t>不是一个完美的解决方案。


渲染国际化文本是痛苦的,所以最好的想法是抓住任何unicode兼容的字符串类(如QString),希望有文本布局引擎(可以正确处理控制字符和双向文本),而不是专注于更有趣的编程问题。


- update -

如果unsigned short不是UTF16,那么unsigned int是什么?那么UTF8是什么呢?这是unsigned char吗?

UTF16可变长度字符编码。UTF16使用1..2每个字符2字节(即uint16_t, 16位)元素。即UTF16字符串中的元素数!= UTF16字符串中的字符数。不能通过计数元素来计算字符串长度。

UTF8是另一个可变长度编码,基于1byte元素(8位,1字节或"unsigned char")。UTF8中的一个unicode字符("码点")为1..4 uint8_t元素。同样,字符串中的元素数!=字符串中的字符数。UTF8的优点是存在于ASCII中的字符在UTF8中每个字符只占用1字节,这节省了一点空间,而在UTF16中,字符总是至少占用2字节。

UTF32固定长度字符编码,每个字符始终使用32位(4字节或uint32_t)。目前,任何unicode字符都可以放入单个UTF32元素中,并且UTF32可能会在很长一段时间内保持固定长度(我不认为地球上所有语言加起来会产生2^31个不同的字符)。它会浪费更多的内存,但是string中的元素数== string中的字符数。

此外,请记住,c++标准并没有规定"int"或"short"应该有多大。