最近接手同事用 C++ 寫的程式,過程中看到使用 JSON Spirit 來處理 JSON 格式,然而,卻發現字串處理有些問題,追了一下才發現這是函式庫沒有使用好而已。

簡單的說,如果要處理 Unicode 的部份,請改用 w開頭系列,如 json_spirit::wmValue 等。

簡易範例:

#include <iostream>
#include <string>
#include <json_spirit/json_spirit.h>
#define JSON_MESSAGE_STRING "{\"message\":\"\\u771f\\u5a01\"}"
#define JSON_MESSAGE_WSTRING L"{\"message\":\"\\u771f\\u5a01\"}"

int main() {
   std::string data = std::string(JSON_MESSAGE_STRING);
   std::cout << "Source: " << data << std::endl;

   json_spirit::mValue mValue;
   json_spirit::read(data, mValue);
   std::cout << "mValue: " << json_spirit::write(mValue) << std::endl;

   std::wstring wdata = std::wstring(JSON_MESSAGE_WSTRING);
   json_spirit::wmValue wmValue;
   json_spirit::read(wdata, wmValue);
   std::wcout << "wmValue:" << json_spirit::write(wmValue) << std::endl;

   return 0;
}

輸出:(在 Mac 上需安裝 Xcode 及其相關 command-tools 後,再用 MacPorts 安裝 boost 即可,接著下載 json_spirit 後,用 cmake 編出 libjson_spirit.a)

> g++ -I/opt/local/include -Ijson_spirit/ test.cpp libjson_spirit.a
> ./a.out
Source: {"message":"\u771f\u5a01"}
mValue: {"message":"\u001F\u0001"}
wmValue:{"message":"\u771F\u5A01"}

可以清楚看到,若不用 std::wstring 這類的處理,解碼就會出錯了。接下來的問題就縮到如何將 std::string 轉到 std::wstring 了 Orz

非常簡易的 std::string to std::wstring 硬轉法:

std::string data;
std::wstring wdata;
wdata.assign(data.begin(), data.end());

至於要輸出 wstring 的方式,繞路一陣子後,終於也找到解法:

std::wstring outwstr = wmValue.get_obj().find(L"message")->second.get_str();
std::cout << "UTF-8:" << boost::locale::conv::utf_to_utf<char>(outwstr) << std::endl;


, , , , , , , ,

changyy 發表在 痞客邦 PIXNET 留言(0) 人氣()