現在來一個實例解析類,直接就把解析JSON到QVariant去了。唯一不足的是沒有搞錯誤處理,具體方法也請各位自行參考JSon-c的發行文檔,這樣比較方便敘述,STL或者Boost我都沒有認真接觸過,不方便寫。
JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式。 易於人閱讀和編寫。同時也易於機器解析和生成。 它基於Javascript Programming Language, Standard ECMA-262 3rd Edition – December 1999的一個子集。 JSON采用完全獨立於語言的文本格式,但是也使用了類似於C語言家族的習慣(包括C, C++, C#, Java, JavaScript, Perl, Python等)。 這些特性使JSON成為理想的數據交換語言。
話說JSON在Web上應用得非常不錯,XML雖然想法很好,但是冗長,解析又麻煩。而JSON作為Javascript的字符描述語言,根本不用手動解析,直接交給Javascript,Eval便可得到結果。而PHP 5.2 以上,更內置了JSON的解析函數,一個函數便把PHP的對象轉換為JSON,比XML來得快得多、方便得多(話說PHP干對象的Serialize和Unserialize是它的強項 )。
今天本文就來說說在C和C++上如何來讀取JSON。實際上解析JSON是比較簡單的,難點在於讀取。另外,以QT為例,這樣比較方便敘述,STL或者Boost我都沒有認真接觸過,不方便寫。
現在JSON解析庫滿天飛,沒有必要再自己寫個了,除非是商業程序 。我試過JsonCPP, QJson, Json-Spirit, jaula等C++的庫。遇到總總問題,有不支持中文(UTF-8編碼也不行)、不方便在Windows下編譯、體積過於臃腫等毛病,最終的選擇是C庫json-c,因為Google看到一篇文章對JSON的各個C庫的優點比較,說JSon-C兼容性最好,而且支持中文(使用UTF-8)。
編譯仍然不是很方便,需要使用configure和GCC。這樣就需要MSYS或者Cygwin了,各位Windows大大需要編譯的話,勞請各位自己Google,安裝最基本的MSYS或者Cygwin,以便使用Bash。另外,MinGW也是必不可少的啦,因為要用GCC和Make嘛。
如若在C++下使用C的庫,頭文件需要特殊處理,解析JSON因為C編譯器及C++編譯器編譯出來的中間代碼的符號不一致,如若不經處理,最後在鏈接的時候定會出現找不到符號的問題。以下是C++的代碼:
- #include <QString>
- #include <QList>
- #include <QMap>
- extern "C"{
- #include <stdio.h>
- #include <stdlib.h>
- #include <JSon.h>
- #include <JSon_object.h>
- #include <JSon_tokener.h>
- }
- .....
- // 忽略上下文的其它代碼,關注我們要的解析方法
- // 1) 解析數組
- char * JSon_string = " [ 10, 20, \"nice\" ] ";
- struct JSon_object *obj, *temp_obj;
- QList< QVariant > data;
- obj = JSon_tokener_parse( JSon_string ); /* 此時的Obj是一個Array */
- for(int i=0 ; i<JSon_object_array_length(obj) ; i++ ){
- temp_obj = JSon_object_array_get_idx(obj, i ); /* 獲取數組的第 i 個元素,作為 temp_obj 保存 */
- switch( JSon_object_get_type( temp_obj ) { /* 判斷 temp_obj 的類型 */
- case JSon_type_string: /* 若是字符串 */
- data.append( JSon_object_get_string(temp_obj) )
- break;
- case JSon_type_int: /* 若是整數 */
- data.append( JSon_object_get_in(temp_obj) )
- break;
- default: /* 其它的類型先不管了 */
- break;
- }
- }
- }
- // 2) 解析對象
- char * JSon_string = " { one: \"good\", \"two\":2 } "
- struct JSon_object *obj, *temp_obj;
- QMap< QString,QVariant > data;
- obj = JSon_tokener_parse( JSon_string );
- JSon_object_object_foreach( obj, key, value ){ // 這裡的key和Value不需要提前聲明。在宏裡作者就給聲明了 -_-|||
- switch( JSon_object_get_type( value ) {
- case JSon_type_string: /* 若是字符串 */
- data.insert( key, JSon_object_get_string(value) )
- break;
- case JSon_type_int: /* 若是整數 */
- data.insert( key, JSon_object_get_in(value) )
- break;
- default: /* 其它的類型先不管了 */
- break;
- }
- ...