如何处理JSON字符串中的unicode值?

时间:2012-10-28 08:14:42

标签: c++ json parsing unicode

我正在用C ++编写JSON解析器,在解析JSON字符串时遇到问题:

JSON规范声明JSON字符串可以包含以下形式的unicode字符:

"here comes a unicode character: \u05d9 !"

我的JSON解析器尝试将JSON字符串映射到std::string,因此通常,JSON字符串的一个字符变为std::string的一个字符。但是对于那些unicode角色,我真的不知道该怎么做:

我应该将原始字节值放在我的std::string中,如下所示:

std::string mystr;
mystr.push_back('\0x05');
mystr.push_back('\0xd9');

或者我应该用iconv这样的库来解释这两个字符,并将UTF-8编码的结果存储在我的字符串中吗?

我应该使用std::wstring存储所有字符吗?那么* {NIX操作系统上wchar_t长4个字节的内容是什么?

我觉得我的解决方案有问题,但我不明白是什么。在那种情况下我该怎么办?

2 个答案:

答案 0 :(得分:12)

经过一番挖掘并感谢H2CO3's commentsPhilipp's comments,我终于明白了这应该如何运作:

阅读RFC4627,第3. Encoding部分:

  
      
  1. 编码

         

    JSON文本应以Unicode编码。默认编码为
      UTF-8。

         

    由于JSON文本的前两个字符始终为ASCII   字符[RFC0020],可以确定是否为八位字节   流是UTF-8,UTF-16(BE或LE),或UTF-32(BE或LE)   在前四个八位字节中的空值模式。

       00 00 00 xx  UTF-32BE
       00 xx 00 xx  UTF-16BE
       xx 00 00 00  UTF-32LE
       xx 00 xx 00  UTF-16LE
       xx xx xx xx  UTF-8
    
  2.   

因此,看起来JSON八位字节流可以用UTF-8,UTF-16或UTF-32编码(在BE或LE变体中,最后两个)。

一旦明确,Section 2.5. Strings解释了如何处理JSON字符串中的\uXXXX值:

  

任何角色都可能被转义。如果角色在基本
中   多语言平面(U + 0000到U + FFFF),然后它可能是
  表示为六个字符的序列:反向固相,然后是
  用小写字母u,后跟四个十六进制数字   编码角色的代码点。十六进制字母A到
  F可以是大写或小写。因此,例如,包含
的字符串   只有一个反向固相字符可以表示为
  “\ u005C”。

对不在Basic Multilingual Plane中的字符进行更完整的解释。

  

转义不在Basic Multilingual中的扩展字符   平面,角色表示为十二个字符的序列,
  编码UTF-16代理对。所以,例如,一个字符串
  仅包含G谱号字符(U + 1D11E)可以表示为
  “\ uD834 \ uDD1E”。

希望这有帮助。

答案 1 :(得分:2)

如果我是你,我会使用std :: string来存储UTF-8和UTF-8。 如果传入的JSON文本不包含任何\ uXXXX序列,则std :: string可以按原样使用,而不是任何转换。

当您解析\ uXXXX时,您可以简单地对其进行解码并将其转换为UTF-8,有效地将其视为真正的UTF-8字符 - 这就是大多数JSON解析器正在做的事情(libjson for肯定)。

当然,使用这种方法用\ uXXXX读取JSON并立即使用你的库将其转储回来可能会丢失\ uXXXX序列并用真正的UTF-8表示替换它们,但是谁真正关心?最终,净结果仍然完全相同。