15

所以我终于回到了我的主要任务——将一个相当大的 C++ 项目从 Windows 移植到 Mac。

我马上就遇到了 wchar_t 在 Windows 上是 16 位但在 Mac 上是 32 位的问题。这是一个问题,因为所有的字符串都由 wchar_t 表示,并且会有字符串数据在 Windows 和 Mac 机器之间来回传输(以磁盘数据和网络数据形式)。由于它的工作方式,在发送和接收数据之前将字符串转换为某种通用格式并不完全简单。

我们最近也真正开始支持更多的语言,因此我们开始处理大量的 Unicode 数据(以及处理从右到左的语言)。

现在,我可能会在这里混淆多个想法,给自己带来比需要更多的问题,这就是我问这个问题的原因。我们认为将所有内存中的字符串数据存储为 UTF-8 是很有意义的。它解决了 wchar_t 大小不同的问题,这意味着我们可以轻松支持多种语言,并且还大大减少了我们的内存占用(我们加载了很多 - 主要是英语 - 字符串) - 但似乎没有很多人在做这个。我们缺少什么吗?您必须处理一个明显的问题,即字符串长度可能小于存储该字符串数据的内存大小。

还是使用 UTF-16 是一个更好的主意?还是我们应该坚持使用 wchar_t 并编写代码在 wchar_t 和 Unicode 之间进行转换,在我们读/写磁盘或网络的地方?

我意识到这很危险地接近征求意见 - 但我们很担心我们忽略了一些明显的东西,因为它似乎没有很多 Unicode 字符串类(例如) - 但是有很多代码可以转换为/来自 Unicode,例如 boost::locale、iconv、utf-cpp 和 ICU。

4

4 回答 4

8

当涉及文件或网络连接时,始终使用为字节定义的协议。不要依赖 C++ 编译器如何在内存中存储任何内容。对于 Unicode 文本,这意味着同时选择编码和字节顺序(好吧,UTF-8 不关心字节顺序)。即使您当前想要支持的平台具有相似的架构,另一个具有不同行为的流行平台,甚至是您现有平台之一的新操作系统也可能会出现,您会很高兴您编写了可移植的代码。

于 2010-11-12T23:35:17.103 回答
2

我倾向于使用 UTF-8 作为内部表示。您只会丢失字符串长度检查,无论如何都不是很有用。对于 Windows API 转换,我使用我在此处设计的自己的 Win32 转换函数。就像 Mac 和 linux 一样(大部分是标准的 UTF-8 感知,不需要在那里转换任何东西)。您获得的免费奖金:

  1. 使用普通的旧std::string.
  2. 逐字节网络/流传输。
  3. 对于大多数语言,良好的内存占用。
  4. 更多功能:utf8cpp
于 2010-11-13T10:25:19.400 回答
1

ICU有一个C++字符串类,UnicodeString

于 2010-11-14T06:45:16.943 回答
1

作为经验法则:UTF-16 用于处理,UTF-8 用于通信和存储。

当然,任何规则都可以被打破,而这条规则不是一成不变的。但是你必须知道什么时候可以打破它。

例如,如果您使用的环境需要其他东西,那么使用其他东西可能是个好主意。但是 Mac OS X API 使用 UTF-16,与 Windows 相同。所以 UTF-16 更有意义。在你把东西放在网上/得到东西之前进行转换(因为你可能在 2-3 个例程中完成它)比进行所有转换来调用 OS API 更直接。

您开发的应用程序类型也很重要。如果它的文本处理很少,对系统的调用也很少(就像电子邮件服务器一样,主要是在不改变它们的情况下移动东西),那么 UTF-8 可能是一个不错的选择。

因此,尽管您可能讨厌这个答案,但“这取决于”。

于 2010-11-13T09:12:43.290 回答