我们不能决定最好的方法:
>在我们的所有应用程序逻辑(和持久数据)中对两者进行标准化,并使其他平台执行适当的转换
>将OS的自然格式用于应用程序逻辑(从而进入操作系统),只能在IPC和持久性的时候进行转换.
对我来说,他们似乎都是相同的.
解决方法
and UTF-8 in linux.
对于现代Linux来说,这一点是正确的.实际编码取决于使用什么API或库.一些硬编码使用UTF-8.但有些读取LC_ALL,LC_CTYPE或LANG环境变量来检测要使用的编码(如Qt库).所以要小心
We can’t decide whether the best approach
像往常一样依赖.
如果90%的代码是以平台特定的方式处理平台特定的API,显然最好使用平台特定的字符串.例如 – 设备驱动程序或原生iOS应用程序.
如果90%的代码是跨平台共享的复杂业务逻辑,显然最好在所有平台上使用相同的编码.作为一个例子 – 聊天客户端或浏览器.
在第二种情况下,您可以选择:
>使用提供字符串支持的跨平台库(例如Qt,ICU)
>使用裸指针(我也认为std :: string一个“裸指针”)
如果使用字符串是应用程序的重要组成部分,那么为字符串选择一个不错的库是一个很好的举措.例如,Qt有一套非常实用的类,涵盖99%的常见任务.不幸的是,我没有ICU的经验,但也看起来很不错.
当使用某些库的字符串时,只有在使用外部库,平台API或通过网络(或磁盘)发送字符串时,才需要关心编码.例如,很多Cocoa,C#或Qt(都有固体字符串支持)程序员对编码细节知之甚少(因为它们可以专注于他们的主要任务).
我使用字符串的经验有点具体,所以我个人更喜欢裸指针.使用它们的代码是非常便于携带的(有意义的是,它可以轻松地在其他项目和平台中重用),因为外部依赖性较少.它非常简单和快速(但可能需要一些经验和Unicode背景感觉).
我同意,裸指针的方法不适合所有人.这是好的:
>你使用整个字符串和分割,搜索,比较是一件难得的事情
>您可以在所有组件中使用相同的编码,只有在使用平台API时才需要进行转换
>所有支持的平台都具有API:
>将您的编码转换为API中使用的编码
>将API编码转换为代码中使用的编码
>指针在您的团队中不是问题
从我一点点具体的经验来看,实际上是一个很常见的情况.
当使用裸指针时,选择将在整个项目(或所有项目)中使用的编码是很好的.
从我的角度来看,UTF-8是一个终极赢家.如果您不能使用UTF-8 – 使用字符串库或平台API的字符串 – 它会节省大量的时间.
UTF-8的优点:
>完全ASCII兼容.任何ASCII字符串都是有效的UTF-8字符串.
> C std库使用UTF-8字符串非常好. (*)
> C std库使用UTF-8(std :: string和friends)很好用. (*)
>旧版代码使用UTF-8非常棒.
>任何平台都支持UTF-8.
>使用UTF-8(由于兼容ASCII),调试更容易.
>没有小端/大端乱
>你不会遇到一个古典的bug“哦,UTF-16并不总是2字节吗?”
(*)直到你需要进行词法比较,变换大小写(toUpper / toLower),改变规范化形式或者这样的东西 – 如果你这样做 – 使用字符串库或平台API.
缺点是有疑问的:
>对于UTF-16,中文(和其他具有较大代码点号码的符号)不太紧凑.
>更难(有点实际)迭代符号.
所以,我建议使用UTF-8作为不使用任何字符串库的项目的通用编码.
但编码不是唯一需要回答的问题.
有一个像normalization这样的东西.简单来说,一些字母可以用几种方式表示,比如一个字形,或者是不同字形的组合.常见的问题是大多数字符串比较功能将它们视为不同的符号.如果您在跨平台项目上工作,则选择标准化形式之一是正确的选择.这将节省您的时间.
例如,如果用户密码包含“йёжиг”,则在Mac(主要使用标准化格式D)和Windows(大多数喜欢标准化表格C)上输入时,将以不同的方式显示UTF-8和UTF-16.所以如果用户在Windows下注册了这样的密码,他会在Mac下登录的问题.
另外我不建议使用wchar_t(或仅在Windows代码中使用它作为UCS-2 / UTF-16字符类型). wchar_t的问题是没有与之相关联的编码.它只是一个抽象的宽字符,大于正常字符(Windows上为16位,大多数nix为32位).