Poe*_*odu 10 c++ unicode encoding locale utf
简短版本:
如果我想写一个无错误的程序,可以安全且可能有效地执行UTF-8/16/32编码操作,我应该遵守哪些规则?
我特别想知道的东西列在长版下面.
长版:
在我的业余生涯中,我学到了很多C++,但直到今天我还没有尝试完全理解字符编码和语言环境.我可以想象,像内存管理有其规则,使您的程序安全,没有泄漏和不可预测的行为,所以他们有字符编码.Inb4:我已经完成了关于这个主题的研究,一直在浏览cppreference并学习了很多新的类,函数和库,但是如果没有足够的解释,我就无法完全理解它.此外,我找不到任何好的而不是过时<locale>的诀窍.所以,继续前进 - 如果我不得不使用标准库字符串编写多语言应用程序:
std::string 用UTF-8?std::wstring (真的不太了解它)std::u16string 用UTF-16?std::u32string 用UTF-32?????????等等?当我们存储UTF-8编码字符时会发生什么变化std::string?它们是否仅限于一个字节的ASCII字符,还是可以是多字节的?
当我执行以下操作时会发生什么?
std::string s = u8"foo";
s += 'x';
Run Code Online (Sandbox Code Playgroud)wchar_t和其他多字节字符类型有什么区别?是wchar_t字符或wchar_t字符串文字能够存储UTF编码的?
根据标题,我问的是C++语言的最新特性 - 来自C++ 17,C++ 14和C++ 11标准.
编辑:
很少有人指出,上面的一些问题是一个非常大的主题,值得单独提问.TODO:添加问题的链接.
Rem*_*eau 10
我应该选择哪个字符串容器?
这取决于您根据自己的特殊需求来决定.您提出的任何选择都有效,它们各有各的优缺点.通常,UTF-8很适合用于存储和通信目的,并且向后兼容ASCII.而UTF-16/32在处理Unicode数据时更容易使用.
std::wstring(真的不太了解它)
大小wchar_t依赖于编译器,甚至取决于平台.例如,在Windows上,wchar_t是2个字节,std::wstring可用于UTF-16编码的字符串.在其他平台上,wchar_t可能是4个字节,而是std::wstring可用于UTF-32编码的字符串.这就是为什么wchar_t/ std::wstring通常不用于可移植代码,以及为什么char16_t/ std::u16string和char32_t/ std::u32string在C++ 11中引入.
我应该完全坚持使用上述容器中的一个或在需要时更换它们吗?
使用适合您需要的任何容器.
通常,您应该在整个代码中使用一种字符串类型.仅在字符串数据进入/离开程序的边界处执行数据转换.例如,在读/写文件,网络通信,平台系统调用等时.
如何在它们之间正确转换?
有很多方法可以解决这个问题.
C++ 11及更高版本有std::wstring_convert/ std::wbuffer_convert.
有第三方Unicode转换库,如ICONV,ICU等.
有C库函数,平台系统调用等.
在使用UTF字符串时,我可以在字符串文字中使用非英文字符,例如波兰字符:
????????等等?
是的,如果您使用适当的字符串文字前缀:
u8 对于UTF-8
L 对于UTF-16或UTF-32(取决于编译器/平台)
u16 对于UTF-16
u32 对于UTF-32
当我们存储UTF-8编码字符时会发生什么变化
std::string?它们是否仅限于一个字节的ASCII字符,还是可以是多字节的?
它们可以是多字节的.就像std::wstring(当wchar_t是2个字节时)并且std::u16string可以保存包含BMP之外的补充字符的字符串,这需要UTF-16代理进行编码.
当字符串容器包含UTF编码的字符串时,每个"字符"只是一个UTF编码的代码单元.UTF-8编码的Unicode一个码点为1-4 CODEUNITS(1-4 char在A S std::string).UTF-16编码码点1-2 CODEUNITS(1-2 wchar_t秒/ char16_t在A S std::wstring/ std::u16string).UTF-32编码码点作为1个codeunit(1个char32_t中的1 个std::u32string).
当我执行以下操作时会发生什么?
Run Code Online (Sandbox Code Playgroud)std::string s = u8"foo"; s += 'x';
正是你所期望的.A std::string持有char元素.无论编码如何,operator+=(char)都只需将单个追加char到最后std::string.
我怎么能区分UTF
char[]和非UTFchar[]还是std::string?
您必须对char[]/ std::stringdata 执行自己的启发式分析,以查看它是否符合UTF.
wchar_t和其他多字节字符类型有什么区别?
字节大小和UTF编码.
char = ANSI/MBCS或UTF-8
wchar_t = UTF-16或UTF-32,具体取决于编译器/平台
char16_t = UTF-16
char32_t = UTF-32
wchar_t字符或wchar_t字符串文字是否能够存储UTF编码?
是,UTF-16或UTF-32,具体取决于编译器/平台.对于UTF-16,单个wchar_t只能保存BMP中的代码点值.wchar_tUTF-32中的单个可以保存任何代码点值.甲wchar_t字符串可以编码所有的码点在任一编码.
如何正确操作UTF字符串(例如toupper/tolower转换)并同时兼容语言环境?
这是一个非常广泛的话题,值得单独提出问题.