解决jsoncpp中文输出为unicode格式的"\u"、VS读取utf8格式中文输出乱码问题

解决jsoncpp中文输出为unicode格式的"\u"、VS读取utf8格式中文输出乱码问题

最近做的项目有一点是将后端传来的json格式数据传入C++后进行计算,再将计算结果输出为json格式返回至后端这一过程就需要jsoncpp。

但是在jsoncpp函数输出的时候,会发现中文字符串变成了"\u"格式的一串乱码,类似这样的,然后就在网上查呀,终于发现一位博主遇到了同样的情况并给出了解决方法。嘿嘿~

https://blog.csdn.net/wgxh05/article/details/82792729超级感谢这位博主!

不过唯一不同的是我用的jsoncpp是master(1.8.4),稍微有点不一样。

1.在src\lib_json\json_writer.cpp中 找到 valueToQuotedStringN函数,这是将值输出为json格式的代码

static JSONCPP_STRING valueToQuotedStringN(const char* value, unsigned length) {
  if (value == NULL)
    return "";

  if (!isAnyCharRequiredQuoting(value, length))
    return JSONCPP_STRING("\"") + value + "\"";
  // We have to walk value and escape any special characters.
  // Appending to JSONCPP_STRING is not efficient, but this should be rare.
  // (Note: forward slashes are *not* rare, but I am not escaping them.)
  JSONCPP_STRING::size_type maxsize = length * 2 + 3; // allescaped+quotes+NULL
  JSONCPP_STRING result;
  result.reserve(maxsize); // to avoid lots of mallocs
  result += "\"";
  char const* end = value + length;
  for (const char* c = value; c != end; ++c) {
    switch (*c) {
    case '\"':
      result += "\\\"";
      break;
    case '\\':
      result += "\\\\";
      break;
    case '\b':
      result += "\\b";
      break;
    case '\f':
      result += "\\f";
      break;
    case '\n':
      result += "\\n";
      break;
    case '\r':
      result += "\\r";
      break;
    case '\t':
      result += "\\t";
      break;
    // case '/':
    // Even though \/ is considered a legal escape in JSON, a bare
    // slash is also legal, so I see no reason to escape it.
    // (I hope I am not misunderstanding something.)
    // blep notes: actually escaping \/ may be useful in javascript to avoid </
    // sequence.
    // Should add a flag to allow this compatibility mode and prevent this
    // sequence from occurring.
    default: {
      unsigned int cp = utf8ToCodepoint(c, end);
      // don't escape non-control characters
      // (short escape sequence are applied above)
      if (cp < 0x80 && cp >= 0x20)
        result += static_cast<char>(cp);
      else if (cp < 0x10000) { // codepoint is in Basic Multilingual Plane
        result += "\\u";
        result += toHex16Bit(cp);
      } else { // codepoint is not in Basic Multilingual Plane
               // convert to surrogate pair first
        cp -= 0x10000;
        result += "\\u";
        result += toHex16Bit((cp >> 10) + 0xD800);
        result += "\\u";
        result += toHex16Bit((cp & 0x3FF) + 0xDC00);
      }
    } break;
    }
  }
  result += "\"";
  return result;
}

其中,default就是将中文转为unicode格式字符串的代码,然后就把源码这一部分改了,将

default: {
      unsigned int cp = utf8ToCodepoint(c, end);
      // don't escape non-control characters
      // (short escape sequence are applied above)
      if (cp < 0x80 && cp >= 0x20)
        result += static_cast<char>(cp);
      else if (cp < 0x10000) { // codepoint is in Basic Multilingual Plane
        result += "\\u";
        result += toHex16Bit(cp);
      } else { // codepoint is not in Basic Multilingual Plane
               // convert to surrogate pair first
        cp -= 0x10000;
        result += "\\u";
        result += toHex16Bit((cp >> 10) + 0xD800);
        result += "\\u";
        result += toHex16Bit((cp & 0x3FF) + 0xDC00);
      }
    } break;

改为

default: 
		result += *c;
		break;

直接将中文字符输出。

2.重新编译jsoncpp库,重新生成lib_json.lib

用VS打开makefiles\msvc2010\jsoncpp.sln,改好上一步之后,重新生成lib_json.lib,替换原来的lib库就好了。

3.如果发现还是有乱码问题,但不是"\u",类似这种,那是VS中遇到UTF8会自动转为ANSI格式代码,这时候需要函数转换为GB2312格式,代码如下:

string UTF8ToGB(const char* str)
{
	string result;
	WCHAR *strSrc;
	LPSTR szRes;

	int i = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
	strSrc = new WCHAR[i + 1];
	MultiByteToWideChar(CP_UTF8, 0, str, -1, strSrc, i);

	i = WideCharToMultiByte(CP_ACP, 0, strSrc, -1, NULL, 0, NULL, NULL);
	szRes = new CHAR[i + 1];
	WideCharToMultiByte(CP_ACP, 0, strSrc, -1, szRes, i, NULL, NULL);

	result = szRes;
	delete[]strSrc;
	delete[]szRes;
	return result;
}

因此在读取数据中,需要添加以上函数进行转换。

猜你喜欢

转载自blog.csdn.net/lpy369369/article/details/84849532