我们无法决定最佳方法:
1. 在所有应用程序逻辑(和持久化数据)中标准化其中一种格式,并使其他平台执行相应的转换。 2. 使用操作系统的自然格式进行应用程序逻辑(从而调用操作系统),并仅在IPC和持久性点进行转换。
对我来说,它们看起来非常相似,都很好。
(*)除非您需要对它们进行词法比较、转换大小写(toUpper/toLower)、更改规范化形式或类似操作,如果需要,请使用字符串库或平台API。
缺点是值得商榷的:
因此,我建议在不使用任何字符串库的项目中使用UTF-8作为通用编码。
但编码并不是您需要回答的唯一问题。
还有一个名为规范化的东西。简单来说,一些字母可以用几种方式表示-例如一个字形或不同字形的组合。这个普遍的问题是大多数字符串比较函数将它们视为不同的符号。如果您正在开发跨平台项目,则选择一个规范化形式作为标准是正确的选择。这将节省您的时间。
例如,如果用户密码包含“йёжиг”,则在Mac上输入(大多使用规范化形式D)和Windows上输入(大多喜欢规范化形式C)时,它将以不同的方式表示(无论是UTF-8还是UTF-16)。因此,如果用户在Windows下注册了这样的密码,则在Mac下登录将成为问题。
此外,我不建议使用wchar_t(或仅在Windows代码中使用它作为UCS-2 / UTF-16字符类型)。 wchar_t的问题是它没有与之相关联的编码。它只是一个比普通char更大的抽象宽字符(在Windows上为16位,在大多数*nix上为32位)。
我会在内部使用相同的编码,并在输入点对数据进行规范化处理。这将涉及更少的代码,更少的问题,并允许您使用相同的跨平台字符串处理库。
我会使用Unicode(UTF-16),因为它在内部处理起来更简单,并且由于每个字符具有恒定的长度,因此应该具有更好的性能。UTF-8非常适合输出和存储,因为它向后兼容拉丁ASCII,并且仅对英文字符使用8位。但在程序内部,16位更简单易用。
C++11提供了新的字符串类型u16string
和u32string
。根据您的编译器版本支持情况和预期寿命,保持向前兼容可能是个好主意。
除此之外,使用ICU库可能是实现跨平台兼容性的最佳选择。
使用UTF-8进行编程很困难,因为长度和偏移量混淆在一起。例如:
std::string s = Something();
std::cout << s.substr(0, 4);
不一定找到前4个字符。
我会使用是什么就用什么。在Windows上,它将是UTF-16。在某些*nix平台上,它可能是UTF-32。
保存到文件时,我建议转换为UTF-8。这通常使文件更小,并消除由于sizeof(wchar_t)
或字节顺序的差异而产生的任何平台依赖性。