- 主题:c++ 里怎么一致地处理unicode?
这个问题我去年发帖子讨论过一次
考虑两个场合:
一、内存处理
如果要在内存中处理大小写转换、不区分大小写查找,UTF8是不合适的。
如果只是字符串拼接处理,那可以用UTF8。
1、可以统一用UTF16(Windows平台用UTF16-LE。其他平台用UTF16-LE或者UTF16-BE,原则是尽量不做LE和BE的转换操作)。
2、不涉及Windows平台而且内存占用不是问题的话,UTF32也可以。基本上没人会在Windows上用UTF32,因为os是用的UTF16-LE,调用os API时都得转为UTF16-LE。
我目前内存中是用wchar_t/std::wstring这种取决于编译器实现的类型,使用者需要清楚它有平台差异(字节数、BE和LE),
这种实际上就是:Windows平台用UTF16-LE,linux和macos用UTF32(是UTF32-LE还是UTF32-BE取决于硬件)。
UTF16有个问题是:大部分字符是16-bit,但是也有32-bit的字符(术语称为surrogate pair)。
所以不如UTF32来得简单痛快,就是吃点内存,也有LE和BE的区分。
下面这种能搜到的大小写转换代码,在Windows上的实现是错误的,不能处理surrogate pair:
void MakeLower(std::wstring &s) {
std::for_each(s.begin(), s.end(), [](WCHAR &c) { c = ::towlower(c); });
}
二、I/O
就像楼上有位说的,UTF8可以用来做输入输出,file、socket等里面的数据用utf8,没有endian问题。
如果同一个file还需要跨平台共享,需要明确file里的存储格式。
三、转换库:
1、Windows上用两个api(WideCharToMultiByte/MultiByteToWideChar),其他平台用iconv或者icu
2、或者统一用iconv或icu
--
FROM 114.241.225.*
不能,CJK扩展字符(Supplementary Ideographic Plane)在UTF16中必须使用surrogate pair也就是32-bit表示。
https://learn.microsoft.com/en-us/globalization/encoding/surrogate-pairs
https://zh.wikipedia.org/wiki/Unicode%E5%AD%97%E7%AC%A6%E5%B9%B3%E9%9D%A2%E6%98%A0%E5%B0%84
第二辅助平面又称为表意文本补充平面(Supplementary Ideographic Plane,缩写SIP,或简称Plane 2),整个范围在U+20000~U+2FFFF。整个平面配置的都是一些罕用的汉字或地区的方言用字,如粤语用字及越南语的字喃。现时摆放了“中日韩统一表意文本扩展B区”(4万3253个汉字)、“中日韩统一表意文本扩展C区”(4149个汉字)、“中日韩统一表意文本扩展D区”(222个汉字)、“中日韩统一表意文本扩展E区”(5762个汉字)、“中日韩统一表意文本扩展F区”(7473个汉字)以及中日韩兼容表意文本增补(CJK Compatibility Ideographs Supplement)。
【 在 finlab 的大作中提到: 】
: 嗯, 如果是windows平台,msvc, 看起来是内部统一使用wstring方便些
: 如果只是处理中文,或者东亚文字, 是不是肯定不会出现四字节字符?
:
--
FROM 114.241.225.*
qt那一大坨,不是每个人都需要
【 在 iwantfly 的大作中提到: 】
: 综上所述, 还是用qstring不香吗
:
--
FROM 114.241.225.*
std里的std::codecvt这些问题多,直接标记为deprecated,可以继续使用,只是编译有警告,一时半会儿也没好的标准出来。
【 在 finlab 的大作中提到: 】
: 以前用QString, 挺好用, 这不是想试试标准库嘛。
:
--
修改:z16166 FROM 114.241.225.*
FROM 114.241.225.*