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;


2013年2月1日 星期五

輸出解碼後的 Unicode ("\u771f\u5a01") 字串 @ Ubuntu 12.04

今天驗證某套 JSON library 到底有沒解碼錯誤,一直再想該怎樣把 '\u' 這類開頭的字串解碼出來,後來就想到幾乎快隨處都可以用的 python 啦


print u"\u771f\u5a01"


如此就解碼完了,搭配 Ubuntu 環境預設是 UTF-8 編碼,在 Terminal 顯示 UTF-8 字串就幾乎無痛了。


2013年1月25日 星期五

[Linux] 將 eml 轉 mbox 格式 @ Ubuntu 12.04

$ sudo apt-get install procmail
$ formail -b < file.eml > file.mbox
$ mutt -f file.mbox


[Linux] 手動掛載 Windows Share (網芳/Samba) @ Ubuntu 12.04

$ sudo apt-get install smbfs
$ sudo mkdir -p /data/samba
$ sudo smbmount //WindowsSambaIP/Path /data/samba -o username=user,password=pass,rw
$ sudo smbmount //WindowsSambaIP/Path /data/samba -o username=guest
$ sudo umount /data/samba


2013年1月24日 星期四

[Linux] sudo echo '+::::::' >> /etc/passwd : Permission denied @ Ubuntu 12.04

有時偷懶寫 script 想要用 echo "somethng" 寫資料到 root 擁有的檔案,就會出現 Permission denied 的訊息:


$ sudo echo '+::::::' >> /etc/passwd
-bash: /etc/passwd: Permission denied


改用下招即可:


$ sudo sh -c "echo '+::::::' >> /etc/passwd"


其實碰到的使用情境是 NIS client 的一堆檔案更新:


$ sudo sh -c "echo '+::::::' >> /etc/passwd" && sudo sh -c "echo '+:::' >> /etc/group" && sudo sh -c "echo '+::::::::' >> /etc/shadow" && sudo sh -c "echo '+:::' >> /etc/gshadow"


補充一點,如果 NIS 尚未設定好時,這時用 sudo 或 login 等相關動作會卡住非常久,從 /var/log/syslog 會看到 … ypbind … : broadcast: RPC: Timed out. 相關訊息,故建議先用 sudo su 轉成 root 角色在安裝 NIS 相關動作 :P