c++ - 在 C++ 程序中使用 unicode

标签 c++ boost unicode

我希望在我的文件同步器应用程序中正确处理带有 Unicode 字符的字符串,但我不知道这种编码是如何工作的?

在 unicode 字符串中,我可以看到 unicode 字符具有这种形式:“\uxxxx” 其中 xs 是数字,普通的 C 或 C++ 程序如何解释这种字符? (为什么'\'后面有一个'u'?有什么作用?)

在互联网上我看到使用“宽字符串或 wchar_t ?? 那么,什么是适合处理 unicode 字符的对象呢?在 rapidJson(支持 Unicode、UTF-8、UTF-16、UTF-32)中,我们可以使用 const char* 来存储可能具有“宽字符”但这些字符需要超过一个字节才能表示的 JSOn。 .我不明白...

这是我暂时找到的那种临时安排(unicode->utf8?ascii?,listFolder是一个std::string):

boost::replace_all(listFolder, "\\u00e0", "à");
boost::replace_all(listFolder, "\\u00e2", "â");
boost::replace_all(listFolder, "\\u00e4", "ä");
...

最佳答案

在 C++ 中处理 Unicode 字符串的合适对象是 icu::UnicodeString (检查边栏中的“API 引用,ICU4C”),至少如果您想要真正处理 Unicode 字符串(而不是仅仅将它们从应用程序的一个点传递到另一个点)。

wchar_t是处理国际字符集的早期尝试,结果失败了,因为 Microsoft 对 wchar_t 的定义因为一旦 Unicode 扩展到代码点 0x10000 之外,两个字节就不够用了。 Linux 定义 wchar_t为四个字节,但不一致使得它(及其派生的 std::wstring )对于可移植编程来说毫无用处。

TCHAR是解析为 char 的 Microsoft 定义默认情况下为 WCHAR如果UNICODE被定义为 WCHAR依次是wchar_t在一定程度的间接...是的。

C++11 给我们带来了 char16_tchar32_t以及相应的字符串类,但它们仍然是 basic_string<> 的实例,因此有它们的缺点,例如当尝试转换具有多个替换字符的大写/小写字符时(例如德语 ß 需要扩展为大写的 SS;标准库不能这样做)。

另一方面,ICU 全力以赴。例如,它提供了标准字符串所不具备的规范化和分解。


\uxxxx\UXXXXXXXX是 unicode 字符转义。 xxxx是表示 UCS-2 代码点的 16 位十六进制数,相当于 Basic Multilingual Plane 中的 UTF-16 代码点 .

XXXXXXXX是一个32位的十六进制数,代表一个UTF-32码位,可以是任意平面。

这些字符转义的处理方式取决于它们出现的上下文(例如,窄/宽字符串),这使得它们有些不完美。

C++11 引入了“适当的”Unicode 文字:

u8"..." 总是 const char[] 采用 UTF-8 编码

u"..." 总是 const uchar16_t[] 采用 UTF-16 编码

U"..." 总是 const uchar32_t[] 采用 UTF-32 编码

如果您使用 \uxxxx\UXXXXXXXX在这三个之一中,字 rune 字将始终扩展为正确的代码单元序列。


请注意,将 UTF-8 存储在 std::string可能,但很危险。您需要了解很多事情:.length()不是字符串中的字符数。 .substr()可能导致部分和无效的序列。 .find_first_of()不会按预期工作。等等。

话虽这么说,在我看来,UTF-8 是唯一任何存储文本合理的编码选择。在某些情况下,将文本作为内存中的 UTF-16 处理(ICU 的方式),但在文件中,除了 UTF-8 之外不接受任何内容。它节省空间,与字节序无关,并且允许即使是完全不知道 Unicode 问题的软件也能进行半正常的处理(请参阅上面的注意事项)。

关于c++ - 在 C++ 程序中使用 unicode,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32994478/

相关文章:

python - 在无法访问库源的情况下将 swig c++ 用于 python

c++ - 二叉搜索树中的插入错误

c++ - 如何 "concatenate"boost::mpl::vectors

c++ - 版本 `CXXABI_1.3.8' 未找到(...需要)

regex - 为什么 Perl 对 Unicode 字符的字符串操作会向字符串添加垃圾?

C++ - char** argv 与 char* argv[]

c++ - 将 lexical_cast 用于无符号类型时检查负值

Java Unicode 到可读文本的转换解码

java - 如何为索引准备 Unicode 字符串?

C++模板制作具有不同常量的多个版本的函数