C++JSON庫(kù)CJsonObject詳解(輕量簡(jiǎn)單好用)
1. JSON概述
JSON: JavaScript 對(duì)象表示法( JavaScript Object Notation) 。是一種輕量級(jí)的數(shù)據(jù)交換格式。 它基于ECMAScript的一個(gè)子集。許多編程語(yǔ)言都很容易找到JSON 解析器和 JSON 庫(kù)。 JSON 文本格式在語(yǔ)法上與創(chuàng)建 JavaScript 對(duì)象的代碼相同。不同語(yǔ)言的不同json庫(kù)對(duì)json標(biāo)準(zhǔn)的支持不盡相同,為了能讓盡可能多的json庫(kù)都能正常解析和生成json,定義JSON的規(guī)范很重要,推薦一個(gè)JSON規(guī)范《JSON風(fēng)格指南》。
2. 常用C&C++ JSON庫(kù)
常用且知名度較高的C&C++的JSON庫(kù)有cJSON、json-c、JsonCpp等,騰訊員工開(kāi)源的一個(gè)RapidJSON以高性能著稱(chēng)。C&C++的JSON庫(kù)比較見(jiàn)RapidJSON作者的比較nativejson-benchmark。
3. 非常簡(jiǎn)單易用的CJsonObject
CJsonObject是基于cJSON全新開(kāi)發(fā)一個(gè)C++版的JSON庫(kù),CJsonObject的最大優(yōu)勢(shì)是輕量(只有4個(gè)文件,拷貝到自己代碼里即可,無(wú)須編譯成庫(kù),且跨平臺(tái)和編譯器)、簡(jiǎn)單好用,開(kāi)發(fā)效率極高,對(duì)多層嵌套json的讀取和生成使用非常簡(jiǎn)單(大部分json解析庫(kù)如果要訪問(wèn)多層嵌套json的最里層非常麻煩)。我一直使用的json庫(kù)是一個(gè)較老版本的cJSON,cJSON的好處是簡(jiǎn)單易用,而且只有兩個(gè)文件,直接復(fù)制到自己的代碼中就可以用。cJSON也有一個(gè)非常容易讓初用者頭痛的地方,一不小心就造成內(nèi)存泄漏了。為此,我基于cJSON封裝了一個(gè)C++版的CJsonObject,該庫(kù)比cJSON更簡(jiǎn)單易用,且只要不是有意不釋放內(nèi)存就不會(huì)發(fā)生內(nèi)存泄漏。用CJsonObject的好處在于完全不用文檔,看完Demo馬上就會(huì)用,不明白的看一下頭文件就知道,所有函數(shù)都十分通俗易懂,最為關(guān)鍵的一點(diǎn)是解析JSON和生成JSON的編碼效率非常高。當(dāng)然,畢竟是經(jīng)過(guò)cJSON封裝而來(lái),效率會(huì)略低于cJSON,cJSON不支持的CJsonObject也不支持。個(gè)人認(rèn)為,既然已經(jīng)選了json,那一點(diǎn)點(diǎn)的解析性能差異就不重要了,如果追求性能可以選protobuf。CJsonObject在我最近5年做過(guò)的8個(gè)項(xiàng)目中廣泛應(yīng)用。CJsonObject非常簡(jiǎn)單易用,且表現(xiàn)穩(wěn)定,2018年5月我把它開(kāi)源https://github.com/Bwar/CJsonObject,并將持續(xù)維護(hù)。
來(lái)看看CJsonObject是如何簡(jiǎn)單易用:
demo.cpp:
#include <string>
#include <iostream>
#include "../CJsonObject.hpp"
int main()
{
int iValue;
std::string strValue;
neb::CJsonObject oJson("{\"refresh_interval\":60,"
"\"dynamic_loading\":["
"{"
"\"so_path\":\"plugins/User.so\", \"load\":false, \"version\":1,"
"\"cmd\":["
"{\"cmd\":2001, \"class\":\"neb::CmdUserLogin\"},"
"{\"cmd\":2003, \"class\":\"neb::CmdUserLogout\"}"
"],"
"\"module\":["
"{\"path\":\"im/user/login\", \"class\":\"neb::ModuleLogin\"},"
"{\"path\":\"im/user/logout\", \"class\":\"neb::ModuleLogout\"}"
"]"
"},"
"{"
"\"so_path\":\"plugins/ChatMsg.so\", \"load\":false, \"version\":1,"
"\"cmd\":["
"{\"cmd\":2001, \"class\":\"neb::CmdChat\"}"
"],"
"\"module\":[]"
"}"
"]"
"}");
std::cout << oJson.ToString() << std::endl;
std::cout << "-------------------------------------------------------------------" << std::endl;
std::cout << oJson["dynamic_loading"][0]["cmd"][1]("class") << std::endl;
oJson["dynamic_loading"][0]["cmd"][0].Get("cmd", iValue);
std::cout << "iValue = " << iValue << std::endl;
oJson["dynamic_loading"][0]["module"][0].Get("path", strValue);
std::cout << "strValue = " << strValue << std::endl;
std::cout << "-------------------------------------------------------------------" << std::endl;
oJson.AddEmptySubObject("depend");
oJson["depend"].Add("nebula", "https://github.com/Bwar/Nebula");
oJson["depend"].AddEmptySubArray("bootstrap");
oJson["depend"]["bootstrap"].Add("BEACON");
oJson["depend"]["bootstrap"].Add("LOGIC");
oJson["depend"]["bootstrap"].Add("LOGGER");
oJson["depend"]["bootstrap"].Add("INTERFACE");
oJson["depend"]["bootstrap"].Add("ACCESS");
std::cout << oJson.ToString() << std::endl;
std::cout << "-------------------------------------------------------------------" << std::endl;
std::cout << oJson.ToFormattedString() << std::endl;
}
Demo執(zhí)行結(jié)果:
[bwar@nebula demo]$ ./CJsonObjectTest
{"refresh_interval":60,"dynamic_loading":[{"so_path":"plugins/User.so","load":false,"version":1,"cmd":[{"cmd":2001,"class":"neb::CmdUserLogin"},{"cmd":2003,"class":"neb::CmdUserLogout"}],"module":[{"path":"im/user/login","class":"neb::ModuleLogin"},{"path":"im/user/logout","class":"neb::ModuleLogout"}]},{"so_path":"plugins/ChatMsg.so","load":false,"version":1,"cmd":[{"cmd":2001,"class":"neb::CmdChat"}],"module":[]}]}
-------------------------------------------------------------------
neb::CmdUserLogout
iValue = 2001
strValue = im/user/login
-------------------------------------------------------------------
{"refresh_interval":60,"dynamic_loading":[{"so_path":"plugins/User.so","load":false,"version":1,"cmd":[{"cmd":2001,"class":"neb::CmdUserLogin"},{"cmd":2003,"class":"neb::CmdUserLogout"}],"module":[{"path":"im/user/login","class":"neb::ModuleLogin"},{"path":"im/user/logout","class":"neb::ModuleLogout"}]},{"so_path":"plugins/ChatMsg.so","load":false,"version":1,"cmd":[{"cmd":2001,"class":"neb::CmdChat"}],"module":[]}],"depend":{"nebula":"https://github.com/Bwar/Nebula","bootstrap":["BEACON","LOGIC","LOGGER","INTERFACE","ACCESS"]}}
-------------------------------------------------------------------
{
"refresh_interval": 60,
"dynamic_loading": [{
"so_path": "plugins/User.so",
"load": false,
"version": 1,
"cmd": [{
"cmd": 2001,
"class": "neb::CmdUserLogin"
}, {
"cmd": 2003,
"class": "neb::CmdUserLogout"
}],
"module": [{
"path": "im/user/login",
"class": "neb::ModuleLogin"
}, {
"path": "im/user/logout",
"class": "neb::ModuleLogout"
}]
}, {
"so_path": "plugins/ChatMsg.so",
"load": false,
"version": 1,
"cmd": [{
"cmd": 2001,
"class": "neb::CmdChat"
}],
"module": []
}],
"depend": {
"nebula": "https://github.com/Bwar/Nebula",
"bootstrap": ["BEACON", "LOGIC", "LOGGER", "INTERFACE", "ACCESS"]
}
}
再來(lái)看看頭文件,一看就知道如何使用:
/*******************************************************************************
* Project: neb
* @file CJsonObject.hpp
* @brief Json
* @author bwarliao
* @date: 2014-7-16
* @note
* Modify history:
******************************************************************************/
#ifndef CJSONOBJECT_HPP_
#define CJSONOBJECT_HPP_
#include <stdio.h>
#include <stddef.h>
#include <malloc.h>
#include <errno.h>
#include <unistd.h>
#include <limits.h>
#include <math.h>
#include <float.h>
#include <string>
#include <map>
#include "cJSON.h"
namespace neb
{
class CJsonObject
{
public: // method of ordinary json object or json array
CJsonObject();
CJsonObject(const std::string& strJson);
CJsonObject(const CJsonObject* pJsonObject);
CJsonObject(const CJsonObject& oJsonObject);
virtual ~CJsonObject();
CJsonObject& operator=(const CJsonObject& oJsonObject);
bool operator==(const CJsonObject& oJsonObject) const;
bool Parse(const std::string& strJson);
void Clear();
bool IsEmpty() const;
bool IsArray() const;
std::string ToString() const;
std::string ToFormattedString() const;
const std::string& GetErrMsg() const
{
return(m_strErrMsg);
}
public: // method of ordinary json object
bool AddEmptySubObject(const std::string& strKey);
bool AddEmptySubArray(const std::string& strKey);
CJsonObject& operator[](const std::string& strKey);
std::string operator()(const std::string& strKey) const;
bool Get(const std::string& strKey, CJsonObject& oJsonObject) const;
bool Get(const std::string& strKey, std::string& strValue) const;
bool Get(const std::string& strKey, int32& iValue) const;
bool Get(const std::string& strKey, uint32& uiValue) const;
bool Get(const std::string& strKey, int64& llValue) const;
bool Get(const std::string& strKey, uint64& ullValue) const;
bool Get(const std::string& strKey, bool& bValue) const;
bool Get(const std::string& strKey, float& fValue) const;
bool Get(const std::string& strKey, double& dValue) const;
bool Add(const std::string& strKey, const CJsonObject& oJsonObject);
bool Add(const std::string& strKey, const std::string& strValue);
bool Add(const std::string& strKey, int32 iValue);
bool Add(const std::string& strKey, uint32 uiValue);
bool Add(const std::string& strKey, int64 llValue);
bool Add(const std::string& strKey, uint64 ullValue);
bool Add(const std::string& strKey, bool bValue, bool bValueAgain);
bool Add(const std::string& strKey, float fValue);
bool Add(const std::string& strKey, double dValue);
bool Delete(const std::string& strKey);
bool Replace(const std::string& strKey, const CJsonObject& oJsonObject);
bool Replace(const std::string& strKey, const std::string& strValue);
bool Replace(const std::string& strKey, int32 iValue);
bool Replace(const std::string& strKey, uint32 uiValue);
bool Replace(const std::string& strKey, int64 llValue);
bool Replace(const std::string& strKey, uint64 ullValue);
bool Replace(const std::string& strKey, bool bValue, bool bValueAgain);
bool Replace(const std::string& strKey, float fValue);
bool Replace(const std::string& strKey, double dValue);
public: // method of json array
int GetArraySize();
CJsonObject& operator[](unsigned int uiWhich);
std::string operator()(unsigned int uiWhich) const;
bool Get(int iWhich, CJsonObject& oJsonObject) const;
bool Get(int iWhich, std::string& strValue) const;
bool Get(int iWhich, int32& iValue) const;
bool Get(int iWhich, uint32& uiValue) const;
bool Get(int iWhich, int64& llValue) const;
bool Get(int iWhich, uint64& ullValue) const;
bool Get(int iWhich, bool& bValue) const;
bool Get(int iWhich, float& fValue) const;
bool Get(int iWhich, double& dValue) const;
bool Add(const CJsonObject& oJsonObject);
bool Add(const std::string& strValue);
bool Add(int32 iValue);
bool Add(uint32 uiValue);
bool Add(int64 llValue);
bool Add(uint64 ullValue);
bool Add(int iAnywhere, bool bValue);
bool Add(float fValue);
bool Add(double dValue);
bool AddAsFirst(const CJsonObject& oJsonObject);
bool AddAsFirst(const std::string& strValue);
bool AddAsFirst(int32 iValue);
bool AddAsFirst(uint32 uiValue);
bool AddAsFirst(int64 llValue);
bool AddAsFirst(uint64 ullValue);
bool AddAsFirst(int iAnywhere, bool bValue);
bool AddAsFirst(float fValue);
bool AddAsFirst(double dValue);
bool Delete(int iWhich);
bool Replace(int iWhich, const CJsonObject& oJsonObject);
bool Replace(int iWhich, const std::string& strValue);
bool Replace(int iWhich, int32 iValue);
bool Replace(int iWhich, uint32 uiValue);
bool Replace(int iWhich, int64 llValue);
bool Replace(int iWhich, uint64 ullValue);
bool Replace(int iWhich, bool bValue, bool bValueAgain);
bool Replace(int iWhich, float fValue);
bool Replace(int iWhich, double dValue);
private:
CJsonObject(cJSON* pJsonData);
private:
cJSON* m_pJsonData;
cJSON* m_pExternJsonDataRef;
std::string m_strErrMsg;
std::map<unsigned int, CJsonObject*> m_mapJsonArrayRef;
std::map<std::string, CJsonObject*> m_mapJsonObjectRef;
};
}
#endif /* CJSONHELPER_HPP_ */
如果覺(jué)得CJsonObject不錯(cuò),別忘了給個(gè)star,謝謝。
到此這篇關(guān)于C++JSON庫(kù)CJsonObject詳解(輕量簡(jiǎn)單好用)的文章就介紹到這了,更多相關(guān)C++JSON庫(kù)CJsonObject內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++與C#互調(diào)dll的實(shí)現(xiàn)步驟
這篇文章主要介紹了C++與C#互調(diào)dll的實(shí)現(xiàn)步驟,dll動(dòng)態(tài)鏈接庫(kù)的共享在一些大型項(xiàng)目中有一定的應(yīng)用價(jià)值,需要的朋友可以參考下2014-08-08
詳解state狀態(tài)模式及在C++設(shè)計(jì)模式編程中的使用實(shí)例
這篇文章主要介紹了state狀態(tài)模式及在C++設(shè)計(jì)模式編程中的使用實(shí)例,在設(shè)計(jì)模式中策略用來(lái)處理算法變化,而狀態(tài)則是透明地處理狀態(tài)變化,需要的朋友可以參考下2016-03-03
C++設(shè)計(jì)模式之適配器模式(Adapter)
這篇文章主要為大家詳細(xì)介紹了C++設(shè)計(jì)模式之適配器模式Adapter,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-03-03
C++結(jié)構(gòu)體初始化的10種寫(xiě)法總結(jié)
這篇文章主要為大家詳細(xì)介紹了10種C++中結(jié)構(gòu)體初始化的寫(xiě)法,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-04-04
C++11/14 線(xiàn)程的創(chuàng)建與分離的實(shí)現(xiàn)
這篇文章主要介紹了C++11/14 線(xiàn)程的創(chuàng)建與分離的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-01-01
C語(yǔ)言實(shí)現(xiàn)動(dòng)態(tài)順序表詳解
這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)動(dòng)態(tài)順序表的實(shí)現(xiàn)代碼的相關(guān)資料,動(dòng)態(tài)順序表在內(nèi)存中開(kāi)辟一塊空間,可以隨我們數(shù)據(jù)數(shù)量的增多來(lái)擴(kuò)容,需要的朋友可以參考下2021-08-08
一篇文章帶你用C語(yǔ)言玩轉(zhuǎn)結(jié)構(gòu)體
本文主要介紹C語(yǔ)言 結(jié)構(gòu)體的知識(shí),學(xué)習(xí)C語(yǔ)言肯定需要學(xué)習(xí)結(jié)構(gòu)體,這里詳細(xì)說(shuō)明了結(jié)構(gòu)體并附示例代碼,供大家參考學(xué)習(xí),有需要的小伙伴可以參考下2021-09-09


