C ++字符串:UTF-8还是16位编码?

时间:2020-03-06 14:26:44  来源:igfitidea点击:

我仍在尝试决定我的(家庭)项目应使用UTF-8字符串(根据需要使用std :: string以及其他特定于UTF-8的函数来实现)还是使用某些16位字符串(实现为std: :wstring)。该项目是一种编程语言和环境(像VB一样,是两者的结合)。

有一些愿望/约束:

  • 如果它可以在有限的硬件(例如内存有限的计算机)上运行,那就太酷了。
  • 我希望代码在Windows,Mac和(如果资源允许)Linux上运行。
  • 我将使用wxWidgets作为我的GUI层,但是我希望与该工具箱交互的代码限制在代码库的一角(我将拥有非GUI可执行文件)。
  • 在处理用户可见的文本和应用程序的数据时,我想避免使用两种不同类型的字符串。

目前,我正在使用std :: string,仅在必要时使用UTF-8操纵函数。它需要较少的内存,这似乎是许多应用程序发展的方向。

如果我们建议使用16位编码,则使用哪种编码:UTF-16? UCS-2?另一个?

解决方案

根据我所读的内容,除非内存不足,否则最好在内部使用16位编码。它可以将几乎所有的生活语言合而为一

我还要看看ICU。如果我们不打算使用字符串的某些STL功能,则使用ICU字符串类型可能更适合我们。

老实说,我从未发现过使用UTF-8以外的任何其他原因的理由。

我建议将UTF-16用于任何类型的数据操作和UI。
Mac OS X和Win32 API使用UTF-16,与wxWidgets,Qt,ICU,Xerces等相同。
对于数据交换和存储,UTF-8可能更好。
参见http://unicode.org/notes/tn12/。

但是无论我们选择什么,我都绝对建议我们使用"仅在必要时"使用UTF-8反对std :: string。

一直使用UTF-16或者UTF-8进行操作,但不要混用,这很麻烦。

MicroATX几乎是一种标准的PC主板格式,最具有4-8 GB的RAM。如果我们使用的是picoATX,则可能限于1-2 GB RAM。即使这样,对于开发环境来说也足够了。出于上述原因,我仍然会坚持使用UTF-8,但是内存不应该成为问题。

UTF-16仍然是可变长度的字符编码(有超过2 ^ 16个unicode码点),因此我们不能执行O(1)字符串索引操作。如果我们正在做很多这样的事情,那么我们并没有节省速度超过UTF-8. 另一方面,如果文本包含许多256-65535范围内的代码点,则UTF-16的大小可能会大大改善。 UCS-2是UTF-16的变体,具有固定长度,其代价是禁止任何大于2 ^ 16的代码点。

在不了解要求的情况下,我个人会选择UTF-8. 由于其他人已经列出的所有原因,这是最容易处理的。

我们是否考虑过使用wxStrings?如果我没记错的话,他们可以执行utf-8 <-> Unicode转换,当我们必须在UI之间传递字符串时,这将使其变得更加容易。

如果我们决定采用UTF-8编码,请查看以下库:http://utfcpp.sourceforge.net/

它可以使生活更加轻松。

实际上,我已经编写了一个广泛使用的应用程序(500万以上的用户),因此,实际上每使用1 KB就加起来。尽管如此,我还是坚持使用wxString。我已经将其配置为从std :: wstring派生,因此我可以将它们传递给需要wstring const&的函数。

请注意,std :: wstring在Mac上是本机Unicode(U + 10000以上的字符不需要UTF-16),因此它使用4个字节/ wchar_t。这样的最大优点是,i ++始终会为我们提供下一个字符。在Win32上,只有99.9%的情况正确。作为一名程序员,我们将了解只有99.9%的比例。

但是,如果我们不相信,可以将该函数写成大写的std :: string [UTF-8]和std :: wstring。这两个功能将告诉我们哪种方法是精神错乱。

磁盘格式是另一回事。为了便于携带,应为UTF-8. UTF-8中没有字节顺序问题,也没有讨论宽度(2/4)。这可能就是为什么许多程序似乎使用UTF-8的原因。

需要说明的一点是,请仔细阅读Unicode字符串比较和规范化。否则,我们将遇到与.NET相同的错误,在那里我们可以拥有两个变量f ???和f ??仅在(不可见的)归一化方面有所不同。