目次
1.中国の文字化けしたソリューション
1.1、文字化けしたディスプレイ
jsoncppを使用して中国語を含む文字列を解析する場合、toStyledString()関数によって生成された文字列の中国語部分は\ uに4桁の16進数を加えたものになり、文字化けした解析が発生します。
といった:
1.2。コードが文字化けしている理由と解決策
jsoncppのソースコードを分析するには(公式ダウンロードアドレス:http://sourceforge.net/projects/jsoncpp/files/ )。StyledWriterのwriteValue関数を分析すると、文字列の処理がvalueToQuotedStringN関数によってエスケープされていることがわかります。
static String valueToQuotedStringN(const char* value, unsigned length) {
if (value == nullptr)
return "";
if (!isAnyCharRequiredQuoting(value, length))
return String("\"") + value + "\"";
// We have to walk value and escape any special characters.
// Appending to String is not efficient, but this should be rare.
// (Note: forward slashes are *not* rare, but I am not escaping them.)
String::size_type maxsize = length * 2 + 3; // allescaped+quotes+NULL
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:が漢字を含む文字を処理することがはっきりとわかります。したがって、ソースコードを変更してライブラリを再コンパイルできます。意志:
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);
}
//result += *c;
}break;
に:
default: {
result += *c;
}break;
最終結果は次のとおりです。
参照リンク:
C ++ jsoncppは、toStyledStringを使用して、文字列の中国語の文字化けソリューションを生成します
次に、\ uXXXX解析を含む文字化けしたコードの解決策
2.1、文字化けしたディスプレイ
jsonファイルは次のとおりです。
分析結果:
2.2文字化けの理由
valueToQuotedStringN関数は以前に変更されています。この関数は文字列をUnicodeエンコーディングに変換するため、\ uXXXX形式で直接読み取られる文字列は実際にはutf-8文字列(中国語を読んでいる場合はUnicodeエンコーディング)です。したがって、ここでは、文字列をUnicodeコードに追加変換する必要があります
2.3。解決策
utf-8からUnicodeへ:
wstring UTF8ToUnicode(const string& str)
{
int len = 0;
len = str.length();
int unicodeLen = ::MultiByteToWideChar(CP_UTF8,
0,
str.c_str(),
-1,
NULL,
0);
wchar_t * pUnicode;
pUnicode = new wchar_t[unicodeLen + 1];
memset(pUnicode, 0, (unicodeLen + 1) * sizeof(wchar_t));
::MultiByteToWideChar(CP_UTF8,
0,
str.c_str(),
-1,
(LPWSTR)pUnicode,
unicodeLen);
wstring rt;
rt = (wchar_t*)pUnicode;
delete pUnicode;
return rt;
}
この関数をプログラムに追加して、次を呼び出します。
std::string ws2s(const std::wstring& ws)
{
std::string curLocale = setlocale(LC_ALL, NULL);
setlocale(LC_ALL, "chs");
const wchar_t* _Source = ws.c_str();
size_t _Dsize = 2 * ws.size() + 1;
char *_Dest = new char[_Dsize];
memset(_Dest, 0, _Dsize);
wcstombs(_Dest, _Source, _Dsize);
std::string result = _Dest;
delete[]_Dest;
setlocale(LC_ALL, curLocale.c_str());
return result;
}
//调用
std::string content = root["Cnki"][i]["content"].toStyledString();
wstring wstr = UTF8ToUnicode(content);//将utf-8转化为unicode格式
cout << ws2s(wstr) << endl;
結果:
参照リンク: