2013年2月2日 星期六

[C++] JSON Spirit Unicode Usage @ Mac OS X 10.8.2

最近接手同事用 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;


沒有留言:

張貼留言