最近做的项目有一点是将后端传来的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(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(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;
}
因此在读取数据中,需要添加以上函数进行转换。