1. 程式人生 > >用jsoncpp 開源庫, 解析json檔案

用jsoncpp 開源庫, 解析json檔案

轉載地址:

https://blog.csdn.net/yc461515457/article/details/52749575

https://blog.csdn.net/u012372584/article/details/78901015

JSON(JavaScript Object Notation, JS 物件標記) 是一種輕量級的資料交換格式。通常用於資料交換或儲存。

JsonCpp是一個基於C++語言的開源庫,用於C++程式的Json資料的讀寫操作。

JsonCpp是一個開源庫

使用

其中最簡單的方法是執行專案根目錄中的python指令碼,構建標頭檔案和原始檔。

1. 在安裝Python環境的控制檯中進入jsoncpp專案根目錄,

2. 執行命令:

python amalgamate.py

3. 將生成的dist目錄拷貝到自己的專案中,其中包原始檔jsoncpp.cpp和標頭檔案json.h、json-forwards.h

基本類和方法

使用jsoncpp庫時需要包含標頭檔案#include <json/json.h>(包含目錄根據需要修改)

方法名稱空間:Json

jsoncpp中主要的類:

Json::Value:可以表示所有支援的型別,如:int , double ,string , object, array等。其包含節點的型別判斷(isNull,isBool,isInt,isArray,

isMember,isValidIndex等),型別獲取(type),型別轉換(asInt,asString等),節點獲取(get,[]),節點比較(過載<,<=,>,>=,==,!=),節點操作(compare,swap,removeMember,removeindex,append等)等函式。

Json::Reader:將檔案流或字串創解析到Json::Value中,主要使用parse函式。Json::Reader的建構函式還允許使用者使用特性Features來自定義Json的嚴格等級。

Json::Writer:與JsonReader相反,將Json::Value轉換成字串流等,Writer類是一個純虛類,並不能直接使用。在此我們使用 Json::Writer 的子類:Json::FastWriter(將資料寫入一行,沒有格式),Json::StyledWriter(按json格式化輸出,易於閱讀)。

Json::Reader可以通過對Json源目標進行解析,得到一個解析好了的Json::Value,通常字串或者檔案輸入流可以作為源目標。

比如in.json檔案為:

{
    "encoding" : "UTF-8",
    "plug-ins" : [
        "python",
        "c++",
        "ruby"
        ],
    "indent" : { "length" : 3, "use_space": true },

"tab-length":[],

"tab":null
}

基本用法:

#include <json.h>
#include <fstream>
#include <iostream>

int createJSON(){
Json::Value root;
root["Result"] = 1;
root["ResultMessage"] = "200";

Json::Value object1;
object1["cpuRatio"] = "4.04";
object1["serverIp"] = "42.159.116.104";
object1["conNum"] = "1";
object1["websocketPort"] = "0";
object1["mqttPort"] = "8883";
object1["TS"] = "1504665880572";

Json::Value object2;
object2["cpuRatio"] = "2.04";
object2["serverIp"] = "42.159.122.251";
object2["conNum"] = "2";
object2["websocketPort"] = "0";
object2["mqttPort"] = "8883";
object2["TS"] = "1504665896981";

Json::Value jarray;
jarray.append(object1);
jarray.append(object2);

root["ResultValue"] = jarray;

Json::StyledWriter  swriter;
std::string jsonstr = swriter.write(root);
std::ofstream  out("create.json");
out << jsonstr;
out.close();

return 0;
}


int main(int argc, char* argv[]) {

	Json::Reader reader;
	Json::Value root;
	Json::FastWriter fwriter;
	Json::StyledWriter swriter;


	const char* s = "in.json";
	std::ifstream  infile;
	infile.open(s);
	// 或者直接 std::ifstream infile(s);

	if (!infile.is_open()) {
		std::cerr << "could not open file: " << *s << std::endl;
		return -1;
	}
		
	if (reader.parse(infile, root)) {
		Json::Value  temp;

		temp = root["encoding"];
		std::cout << temp.asString()<< std::endl << std::endl;

		temp = root["plug-ins"];
		int size = temp.size();
		for (int i = 0; i < size; i++) {		  
			std::cout << temp[i].asString()<<std::endl<<std::endl;
		}

		temp = root["indent"];
		std::cout << temp["length"].asInt() << std::endl << std::endl;
		std::cout << temp["use_space"].asBool() << std::endl << std::endl;	
	}
	infile.close();
	

	std::ofstream outfile;
	outfile.open("out_fast.json");  //沒有的話,建立,開啟; 否則,清空其內容,開啟
	//std::ofstream  outfile("out.json"); 

	std::string str = fwriter.write(root);
	outfile << str << std::endl << std::endl;
	outfile.close();

	str = swriter.write(root);
	outfile.open("out_style.json");
	outfile << str << std::endl << std::endl;
	outfile.close();


	if (root.isMember("encoding"))
		std::cout << "encoding existed" << std::endl;
	if (!root.isMember("enco"))
		std::cout << "enco not exist!!" << std::endl;

	if (root["tab"].isNull()) 
		std::cout << "tab isNull" << std::endl;//print isNull
		
	if (root.isMember("tab-length")) {//true
		if (root["tab-length"].isNull()) 
		      std::cout << "tab-length isNull" << std::endl;		
		else std::cout << "tab-length not Null" << std::endl;
		// print "tab-length not Null", there is a array object([]), through this array object is empty
		std::cout << "empty: " << root["tab-length"].empty() << std::endl;//print empty: 1
		std::cout << "size: " << root["tab-length"].size() << std::endl;//print size: 0
	}

	bool flag = root["anything-not-exist"].asBool();//false
	std::cout << "flag: " << flag<<std::endl;
	flag=root.isMember("anything-not-exist"); //true
	std::cout << "flag: " << flag<<std::endl;

	//typedef std::vector<std::string> Json::Value::Members
	Json::Value::Members  key_list = root.getMemberNames();

	root.removeMember("encoding");

	system("pause");

	createJSON();

	return 0;

}
最後生成的create.json為:
{
   "Result" : 1,
   "ResultMessage" : "200",
   "ResultValue" : [
      {
         "TS" : "1504665880572",
         "conNum" : "1",
         "cpuRatio" : "4.04",
         "mqttPort" : "8883",
         "serverIp" : "42.159.116.104",
         "websocketPort" : "0"
      },
      {
         "TS" : "1504665896981",
         "conNum" : "2",
         "cpuRatio" : "2.04",
         "mqttPort" : "8883",
         "serverIp" : "42.159.122.251",
         "websocketPort" : "0"
      }
   ]
}

其他操作:

《1》判斷Key值是否存在

bool Json::Value::isMember (constchar * key)const
bool Json::Value::isMember (const std::string & key)const
bool Json::Value::isMember (constchar*key,constchar * end ) const

《2》判斷value是否為NULL
bool Json::Value::isNull ( ) const

《3》另外值得強調的是,Json::Value和C++中的map有一個共同的特點,就是當你嘗試訪問一個不存在的 key 時,會自動生成這樣一個key-value預設為null的值對。也就是說解析時,先判斷key是否存在,然後判斷value是否為null,再根據型別取值

bool flag = root["anything-not-exist"].asBool();//false
std::cout << "flag: " << flag<<std::endl;
flag=root.isMember("anything-not-exist"); //true
std::cout << "flag: " << flag<<std::endl;
《4》獲取所有的key

//typedef std::vector<std::string> Json::Value::Members
Json::Value::Members  key_list = root.getMemberNames();

《5》刪除成員

root.removeMember("encoding");