輕量c++ json庫(源碼精簡適合學習)

github地址:https://github.com/HuangHongkai/ejson

介紹

該庫爲輕量級的c++ json解析與構造庫,源碼很短,適合學習,覺得ok的點個star吧。

提供了的功能:

  • json字符串解析爲c++對象(JSONArray和JSONObject)
  • c++對象中獲取key-value值
  • c++對象轉化爲json字符串

除此之外,由於json支持了多種數據類型,還可以將JSONArray對象看成是python的list,JSONObject看成是python的dict,庫中提供了方便操作的api函數。例如以下初始化方法,

JSONArray arr = {123.4, "dfsdf", 23, nullptr}; // 類似於python的list
JSONArray arr2 = LIST(1.23, "sdfsdg", 234, nullptr); //提供一個LIST初始化宏,類似於python的list
JSONObject obj = {
    {"test obj", {"key", "value"}},
    {"int number", 2},
    {"float number", 34.3},
    {"my string", "fsdfsdg"},
    {"nullptr", nullptr},
    {"emptylist", {}},
}; // 可以看成是python的dict
JSONObject obj2 = OBJECT(
            KEYVALUE("username", "hhk"),
            KEYVALUE("obj", OBJECT(
                    KEYVALUE("abcd", LIST(1,2.3, "hahahaha")),
                    KEYVALUE("obj", OBJECT(
                            KEYVALUE("key", "this is obj.obj.key' s value")
                    ))
            )),
            KEYVALUE("null", nullptr),
            KEYVALUE("list", LIST(1, "qwerty", 2.34, OBJECT(
                            KEYVALUE("key", "this is a key"),
                            KEYVALUE("key2", "this is a key2"),
                    ))),
    		);  // 提供了一個初始化宏,類似於python的dict
// 注:使用OBJECT LIST初始化宏的目的是爲了替代{}來進行初始化,因爲有時候大括號看起來會不夠直觀。

實現該庫的一些技巧:

  • 參考boost any.hpp ,實現一個可以在容器裏容納任意類型的對象

  • typeid 進行類型的判斷

  • 使用了很多遞歸方法

編譯

編譯依賴:

  • cmake
  • gcc

如果是windows平臺推薦使用cygwin套件(可以在windows下編譯linux軟件),配合clion,開發起來挺方便的。

例如windows平臺下(linux下類似),編譯靜態庫的方法如下,編譯成功後在build目錄下生成libejson.a靜態庫。

在這裏插入圖片描述
此時在build目錄下生成ejson_test.exe和libejson.a,直接運行ejson_test.exe即可。

手動編譯測試程序方法如下:(-lejson參數表示鏈接libejson.a靜態庫)

在這裏插入圖片描述

提供方便的API

這裏Json支持的類型有int, float, double, const char* , string, nullptr(cpp中的空指針)

  1. JSON Array

    • 使用 [] 操作符寫入數據,可以使用cout直接打印輸出

      JSONArray test1(2); // 初始化分配大小,可以會自動拓展容量
      test1[0] = nullptr;
      test1[1] = "this is const char*";
      test1[2] = 12324.5;
      test1[5] = "中文字符串";
      cout << test1 << endl;
      
    • 初始化列表構造函數與鏈式操作

      JSONArray arr = {123.4, "dfsdf", 23, nullptr}; // 初始化列表 
      arr[0] = 12.314;
      arr[2] = 2335;
      arr[3] = "字符串";
      arr[6] = obj;  // json對象
      arr.add(123456) // 整數
         .add(234.235236) //浮點數
         .add("字符串") //字符串
         .add(nullptr); // null測試
      
    • get方法獲取數值

      例如 float f = test1.get<float>(2); ,如果類型不正確的話會拋出異常

    • toString方法轉換爲字符串,toString可選參數,代表縮進的數量。

      例如 test1.toString(4) 表示4空格縮進

  2. JSON Object

    • 使用 [] 來寫入數據

      // 使用[] 操作對象
      JSONObject test2;
      test2["float"] = 123.456;
      test2["int"] = 24;
      test2["string"] = "this is a string";
      test2["array"] = test1;
      test2["nullptr"] = nullptr;
      cout << test2 << endl;
      
    • 更加複雜的初始化方法

      這種方法看起來比較直觀,支持object和array的嵌套使用,這是我自己想出來的,有興趣的朋友可以看下我的實現方法,討論下有沒有更加優秀的實現方式。

      // obj初始化方法
      JSONObject obj = {
          {"test obj", {"key", "value"}},
          {"int number", 2},
          {"float number", 34.3},
          {"my string", "fsdfsdg"},
          {"nullptr", nullptr},
          {"emptylist", {}},
          {"列表嵌套列表", {1,2.3, "sdf", {1,2.242, "float"}}}, // 列表嵌套
          {"列表嵌套對象和列表", {
              {{"key1", 1234}}, // 被認爲是對象
              {"key1", 1234}, // 被認爲是列表
              1.23,
              234325
          }},
          {"對象", { // 所有的值都是{key, value}對則認爲是嵌套對象
              {"a obj", 1234566},
              {"b obj", "b obj value"},
          }}
      };
      

      這種方法有時候還是有點不夠直觀,所以我弄了一個宏,使得編寫json時更加直觀

      JSONObject context = OBJECT(
                  KEYVALUE("username", "hhk"),
                  KEYVALUE("obj", OBJECT(
                          KEYVALUE("abcd", LIST(1,2.3, "hahahaha")),
                          KEYVALUE("obj", OBJECT(
                                  KEYVALUE("key", "this is obj.obj.key' s value")
                          ))
                  )),
                  KEYVALUE("null", nullptr),
                  KEYVALUE("list", LIST(1, "qwerty", 2.34, OBJECT(
                                  KEYVALUE("key", "this is a key"),
                                  KEYVALUE("key2", "this is a key2"),
                          ))),
                  KEYVALUE("list1", LIST(1,2,3,4,5)),
                  KEYVALUE("list2", LIST(1,2,3)),
                  KEYVALUE("obj2", OBJECT(
                          KEYVALUE("key1", "value1"),
                          KEYVALUE("key2", 222),
                          KEYVALUE("key3", 333),
                  )),
                  KEYVALUE("a", "111"),
                  KEYVALUE("b", "222"),
                  KEYVALUE("c", "333"),
          );
      

      這裏有三個宏,分別是OBJECT,KEYVALUE, LIST。

    • 支持鏈式add的操作

      obj["int"] = 12325;
      obj["float"] = 24235.235235;
      obj["string"] = "this is a string2";
      obj["null"] = nullptr;
      
      obj.add("int", 123) // 整數
          .add("float", 23.2324) // 浮點數
          .add("string", "this is a string") // 英文字符串
          .add("中文", "這是中文字符串。。。") // 中文字符串
          .add("symbols  \",.[]@!#$%^", "含有特殊符號\"") // 特殊符號
          .add("list", {1, 2.34, "english string", 123.4, "中文字符串"}) // 列表
          .add("this is null", nullptr) // null測試
          .add("object", {{"key1", "value1"}, {"key2", 223}, {"key3", 23.4}}); // 對象
      
    • get 方法獲取數值

      例如, obj->get<string>("string") 可以獲取到鍵爲string的值。

    • toString方法輸出字符串,參數爲縮進的數量

      例如4空格縮進如下(obj.toString(4))

      1551941891253

      無縮進(obj.toString(-1)

      在這裏插入圖片描述
      無空格縮進(obj.toString(0))
      在這裏插入圖片描述

  3. 字符串轉換爲json對象

    由於我們不知道字符串是array還是object,我們使用JSONBase類來接受返回的結果。

    (JSONBase中有isJSONArray 和 isJSONArray 方法,可以方便我們進行類型判斷)

    例如以下,

    string parse_str = R"({"name" : "hhk" , "key1": "valu\"e1 ","key2":[1,2,"asd",{"sadf": 123, "sb": 12.3}, 123.3]})";
    JSONBase* a = JSONBase::parse(parse_str);
    cout << *a << endl;
    JSONObject *b = dynamic_cast<JSONObject *>(a); //類型轉換
    cout << b->get<string>("key1") << endl;
    cout << b->get<JSONArray>("key2").get<int>(1) << endl;
    

    parse方法用於不知道字符串是array還是object,parse_obj方法返回JSONObject,parse_arr方法返回JSONArray。(parse_obj,parse_arr用於明確知道字符串的類型)

    如果字符串不是json字符串,則拋出JSONParseException異常。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章