首页 文章

在C程序中使用unicode

提问于
浏览
0

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

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

在互联网上我看到使用“宽字符串或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", "ä");
...

2 回答

  • 2

    在C中处理Unicode字符串的合适对象是icu::UnicodeString(在边栏中检查"API References, ICU4C"),至少如果你想真正处理Unicode字符串(而不是只是将它们从你的应用程序的一个点传递到另一个点) .

    wchar_t 是处理国际字符集的早期尝试,结果证明这是一次失败,因为一旦Unicode扩展到代码点0x10000以后,微软将 wchar_t 定义为两个字节就证明是不够的 . Linux将 wchar_t 定义为四个字节,但不一致使得它(及其派生的 std::wstring )对于可移植编程而言毫无用处 .

    TCHAR 是默认情况下解析为 char 的Microsoft定义,如果定义 UNICODE 则为 WCHARWCHAR 依次为间接级别 wchar_t ...是的 .

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

    另一方面,ICU全力以赴 . 例如,它提供标准化和分解,而标准字符串则不提供 .


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

    XXXXXXXX 是一个32位十六进制数,表示UTF-32代码点,可以是任何平面 .

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

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

    u8"..." 始终是UTF-8编码的 const char[] .

    u"..." 始终是UTF-16编码的 const uchar16_t[] .

    U"..." 始终是UTF-32编码的 const uchar32_t[] .

    如果在这三个中的一个中使用 \uxxxx\UXXXXXXXX ,则字符文字将始终扩展为正确的代码单元序列 .


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

    话虽如此,在我看来,UTF-8是任何存储文本唯一合理的编码选择 . 有些情况需要处理文本作为UTF-16内存(ICU的方式),但在文件中,节省空间,独立于endianess,并允许甚至通过软件进行半合理处理幸福地没有意识到Unicode问题(见上面的警告) .

  • 5

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

    这是一个unicode字符转义序列 . 它将被解释为unicode角色 . 转义字符后面的 u 是语法的一部分,它将它与其他转义序列区分开来 . 有关更多信息,请阅读documentation .

    那么,处理unicode字符的合适对象是什么?

    • char 对于uft-8

    • char16_t for utf-16

    • char32_t for utf-32

    • wchar_t 的大小取决于平台,因此您无法对其编码进行可移植的假设西装 .

    我们可以使用const char *来存储可能具有“宽字符”的JSOn,但这些字符需要多于一个字节来表示...

    如果你的意思是你可以在 char 字符串中存储多字节utf-8字符,那么你是对的 .

    这是我目前发现的那种临时安排(unicode-> utf8?ascii?,listFolder是一个std :: string)

    你试图做的是用一些具有plaftorm定义编码的字符替换一些unicode字符 . 如果除此之外还有其他unicode字符,那么最终会得到一个混合编码的字符串 . 此外,在某些情况下,它可能会意外地替换其他字节序列的一部分 . 我建议使用库来转换编码或对编码的字符串进行任何其他操作 .

相关问题