Jsoncpp如何使用及样例

下载对应的版本

下载:https://github.com/184622608/jsoncpp
注意:主要两个大的版本,一个支持C++11, 一个不支持
1.y.z is built with C++11.
0.y.z can be used with older compilers.
我公司这里使用的是旧的不运行C++11的编译器里使用,所以只能选择0.y.z的版本下载

如何在项目中使用

我这里是直接使用源码配合使用做成其它功能,然后编译成动态库

1,生成合并的头和源文件

它这里是使用pthon来生成一个合并的头文件与源文件(this requires Python 2.6):
python amalgamate.py

It is possible to specify header name. See the -h option for detail.

By default, the following files are generated:

1. dist/jsoncpp.cpp: 
   source file that needs to be added to your project.

2. dist/json/json.h: 
   corresponding header file for use in your project.
   It is equivalent to including json/json.h in non-amalgamated source. 
   This header only depends on standard headers.

3. dist/json/json-forwards.h: 
   header that provides forward declaration of all JsonCpp types.

The amalgamated sources are generated by concatenating JsonCpp source in the correct order and defining the macro JSON_IS_AMALGAMATION to prevent inclusion of other headers.

2,在项目使用

你的生成目录\jsoncpp\jsoncpp-0.y.z\dist\

1,将dist目录下的 json头文件目录 和 json.cpp 拷贝到 你的项目里
2,在你的项目中属性 >> 配置属性 >> C/C++ >> 附加包含目录 包含 json 目录
3,在你想使用jsoncpp的源文件中包含头文件
#include "json/json.h"
4,解析json数据
例1:

要解析的数据如下:

{"retCode":"0000","retMsg":"成功",
	"keyCurVerList":
	[{
		"issueChannelCode":"01","keyId":"01","keyBathNumber":"2","needUpdateYN":"Y",
		"keyList":
		[
		{"keyBathNumber":"2","keyIdx":"01","keyValue":"1111111111","keyEffectiveDate":"20271101"},
		{"keyBathNumber":"2","keyIdx":"02","keyValue":"2222222222","keyEffectiveDate":"20271101"},
		{"keyBathNumber":"2","keyIdx":"03","keyValue":"3333333333","keyEffectiveDate":"20271101"},
		{"keyBathNumber":"2","keyIdx":"04","keyValue":"4444444444","keyEffectiveDate":"20271101"},
		{"keyBathNumber":"2","keyIdx":"05","keyValue":"5555555555","keyEffectiveDate":"20271101"},
		{"keyBathNumber":"2","keyIdx":"06","keyValue":"6666666666","keyEffectiveDate":"20271101"},
		{"keyBathNumber":"2","keyIdx":"07","keyValue":"7777777777","keyEffectiveDate":"20271101"},
		{"keyBathNumber":"2","keyIdx":"08","keyValue":"8888888888","keyEffectiveDate":"20271101"},
		{"keyBathNumber":"2","keyIdx":"09","keyValue":"9999999999","keyEffectiveDate":"20271101"},
		{"keyBathNumber":"2","keyIdx":"0A","keyValue":"AAAAAAAAAA","keyEffectiveDate":"20271101"}
		]
	}]
}
// 根据要解析的数据定义相对应的结构体
struct ST_Key
{
	std::string keyBathNumber;
	std::string	keyIdx;
	std::string	keyValue;
	std::string	keyEffectiveDate;
};

struct ST_KeyCurVer
{
	std::string issueChannelCode;
	std::string keyId;
	std::string keyBathNumber;
	std::string needUpdateYN;
	
	std::vector keyList;
};

struct ST_KeySync_Ret
{
	std::string retCode;
	std::string retMsg;

	std::vector keyCurVerList;
};

// 使用方法
// 接收到要解析的json内容存储在 string revc_text 中
Json::Reader reader;
Json::Value value;
if (reader.parse(recv_text, value))  //revc_text要解析的json文本
{
	ret.retCode = value["retCode"].asString(); //ST_KeySync_Ret ret为本地要存储json数据定义的结构体
	ret.retMsg = value["retMsg"].asString();

	const Json::Value arrayObj = value["keyCurVerList"];
	for (int i = 0; i < arrayObj.size(); ++i)
	{
		ST_KeyCurVer keyCurVer; //自定义的结构体

		keyCurVer.issueChannelCode = arrayObj[i]["issueChannelCode"].asString();
		keyCurVer.keyId = arrayObj[i]["keyId"].asString();
		keyCurVer.keyBathNumber = arrayObj[i]["keyBathNumber"].asString();
		keyCurVer.needUpdateYN = arrayObj[i]["needUpdateYN"].asString();

		const Json::Value subArrayObj = arrayObj[i]["keyList"];
		for (int j = 0; j < subArrayObj.size(); ++j)
		{
			ST_Key key; //自定义的结构体

			key.keyBathNumber = subArrayObj[j]["keyBathNumber"].asString();
			key.keyIdx = subArrayObj[j]["keyIdx"].asString();
			key.keyValue = subArrayObj[j]["keyValue"].asString();
			key.keyEffectiveDate = subArrayObj[j]["keyEffectiveDate"].asString();
			
			keyCurVer.keyList.push_back(key);
		}

		ret.keyCurVerList.push_back(keyCurVer);
	}
}
例2:
//  要解析的json文本
//  {"retCode":"0000","retMsg":"成功","adviceOpt":["006"],"managerCode":"","transAmount":"0"}

	Json::Reader reader;
	Json::Value value;
	if (reader.parse(recv_text, value)) //revc_text要解析的json文本
	{
		ret.retCode = value["retCode"].asString();
		ret.retMsg = value["retMsg"].asString();

		ret.managerCode = value["managerCode"].asString();
		ret.transAmount = value["transAmount"].asString();

		const Json::Value arrayObj = value["adviceOpt"];
		for (int i = 0; i < arrayObj.size(); ++i)
		{
			ret.adviceOpt = arrayObj[i].asString();
		}
	}

生成Json数据字符串

	/*
	{
		"device_id":"3984723987923784936",
		"mobile":"13020149283",
		"device_type":"android",
		"account_id_hash":"123456789",
		"source_ip":"111.111.111.111"
	}
	*/
	m_risk.insert(std::make_pair("device_id", data.riskinfo.device_id));
	m_risk.insert(std::make_pair("mobile", data.riskinfo.mobile));
	m_risk.insert(std::make_pair("device_type", data.riskinfo.device_type));
	m_risk.insert(std::make_pair("account_id_hash", data.riskinfo.account_id_hash));
	m_risk.insert(std::make_pair("source_ip", data.riskinfo.source_ip));

	Json::Value root;
	std::map::iterator it = m_risk.begin();
	for (;it != m_risk.end(); ++it){
		root[it->first] = it->second;
	}

	Json::FastWriter writer;
	std::string str_risk = writer.write(root);
	/*
	{"account_id_hash":"123456789","device_id":"3984723987923784936","device_type":"android","mobile":"13020149283","source_ip":"111.111.111.111"}
	*/


	// 如果想要排列好看的字符串
	std::string str_risk_styled= root.toStyledString();
	/*
	{
	   "account_id_hash" : "123456789",
	   "device_id" : "3984723987923784936",
	   "device_type" : "android",
	   "mobile" : "13020149283",
	   "source_ip" : "111.111.111.111"
	}
	*/

进一步的了解

Json::Value

Json::Value 用来表示Json中的任何一种value抽象数据类型,具体来说,Json中的value可以是一下数据类型:

  • 有符号整数 signed integer [range: Value::minInt - Value::maxInt]
  • 无符号整数 unsigned integer (range: 0 - Value::maxUInt)
  • 双精度浮点数 double
  • 字符串 UTF-8 string
  • 布尔型 boolean
  • 空 ‘null’
  • 一个Value的有序列表 an ordered list of Value
  • collection of name/value pairs (javascript object)

可以通过 [ ] 下标的方法来取值。

//Examples:
Json::Value null_value; // null
Json::Value arr_value(Json::arrayValue); // []
Json::Value obj_value(Json::objectValue); // {}

Json::Reader

Json::Reader可以通过对Json源目标进行解析,得到一个解析好了的Json::Value,通常字符串或者文件输入流可以作为源目标。

假设现在有一个example.json文件

{
    "encoding" : "UTF-8",
    "plug-ins" : [
        "python",
        "c++",
        "ruby"
        ],
    "indent" : { "length" : 3, "use_space": true }
}
使用Json::Reader对Json文件进行解析
bool parse (const std::string &document, Value &root, bool collectComments=true)
bool parse (std::istream &is, Value &root, bool collectComments=true)
// 使用方法
Json::Value root;
Json::Reader reader;
std::ifstream ifs("example.json");//open file example.json

if(!reader.parse(ifs, root)){
   // fail to parse
}
else{
   // success
   std::cout<
使用Json::Reader对字符串进行解析
bool Json::Reader::parse ( const char * beginDoc,
        const char * endDoc,
        Value & root,
        bool collectComments = true 
    )   
  Json::Value root;
  Json::Reader reader;
  const char* s = "{\"uploadid\": \"UP000000\",\"code\": 100,\"msg\": \"\",\"files\": \"\"}"; 
  if(!reader.parse(s, root)){
    // "parse fail";
  }
  else{
      std::cout << root["uploadid"].asString();//print "UP000000"
  }

测试样例

#include 
#include 
#include 

#include "json/json.h"

using namespace std;

void WriteJsonData(const char* filename)  
{  
	// 测试自定义json数据,存储在一个新的文件中
	{
		Json::Value root; 

		// 写入到一个新的文件中,也可以当字符串使用
		std::ofstream os;  
		os.open(filename, std::ios_base::out);

		root["retCode"] = "0000";
		root["retMsg"] = "成功";

		Json::Value arrayObj;   // 构建对象 
		arrayObj[0] = "000";
		arrayObj[1] = "001";
		arrayObj[2] = "002";
		root["adviceOpt"] = arrayObj;

		Json::Value arrayObj1;   // 构建对象
		arrayObj1[0]["keyBathNumber"] = "1";
		arrayObj1[0]["keyIdx"] = "01";
		arrayObj1[0]["keyValue"] = "1111111111";

		arrayObj1[1]["keyBathNumber"] = "2";
		arrayObj1[1]["keyIdx"] = "02";
		arrayObj1[1]["keyValue"] = "2222222222";
		root["keylist"] = arrayObj1;

		cout << root.toStyledString() << endl;
		os << root;
		os.close();  
	}
	

	// 测试在一个有json数据的文件中读取数据然后添加或修改并存储在一个新的文件中
	{
		Json::Reader reader;  
		Json::Value root; 

		std::ifstream is;  
		is.open(filename, std::ios::binary);
		if (reader.parse(is, root))  
		{
			root["retMsg"] = "失败";

			root["adviceOpt"][2] = "003";
			root["adviceOpt"][3] = "002";

			root["keylist"][1]["keyIdx"] = "33";
			root["keylist"][1]["keyValue"] = "333333333";   

			std::string out = root.toStyledString();  
			cout << out << endl;

			// 输出无格式json字符串    
			Json::FastWriter writer;  
			std::string strWrite = writer.write(root);  
			std::ofstream ofs;  
			ofs.open("test_write.json");  
			ofs << strWrite;  
			ofs.close();  
		}
		is.close();
	}
}  

int main()
{
	// 读取的使用 
	// 1,读取字符串
	{
		/* {"encoding" : "UTF-8","plug-ins" : ["python","c++","ruby"],
		                                         "indent" : { "length" : 3, "use_space": true}}*/
		string test_txt = "{\"encoding\" : \"UTF-8\",\"plug-ins\" : [\"python\",\"c++\",
		                        \"ruby\"],\"indent\" : { \"length\" : 3, \"use_space\": true}}";
		cout << test_txt << endl;

		cout << "//////////////////////////////////////////////////////////////////////" << endl;
		Json::Reader reader;
		Json::Value value;
		if (reader.parse(test_txt, value))
		{
			// encoding
			cout << value["encoding"].asString() << endl;

			// 关于plug-ins
			// 方法1
			const Json::Value arrayObj1 = value["plug-ins"];
			for (int i = 0; i < arrayObj1.size(); ++i)
			{
				cout << arrayObj1[i].asString() << " ";
			}
			cout << endl;
			// 方法2
			cout << value["plug-ins"][0].asString() << " ";
			cout << value["plug-ins"][1].asString() << " ";
			cout << value["plug-ins"][2].asString() << " ";
			cout << endl;

			// 关于indent
			// 方法1
			const Json::Value arrayObj2 = value["indent"];
			cout << arrayObj2["length"].asString() << " ";
			cout << arrayObj2["use_space"].asString() << " ";
			cout << endl;
			// 方法2
			cout << value["indent"]["length"].asString() << " ";
			cout << value["indent"]["use_space"].asString() << " ";
			cout << endl;
		}
	}
	
	// 2,读取文件
	{
		Json::Value value;
		Json::Reader reader;
		std::ifstream ifs("example.json");//open file example.json

		if(reader.parse(ifs, value)){
			// success
			cout << value["encoding"].asString() << endl;
			cout << value["plug-ins"][0].asString() << endl;
			cout << value["indent"]["length"].asInt() << endl;
		}
		else{
			// fail to parse
			
		}
	}

	// 3,写入本地文件
	{
		Json::Value value;
		Json::Reader reader;
		Json::FastWriter fwriter;
		Json::StyledWriter swriter;

		std::ifstream ifs("example.json");//open file example.json
		if(! reader.parse(ifs, value)){
			// parse fail
			return 0;
		}

		// 紧凑型
		std::string str = fwriter.write(value);
		std::ofstream ofs("example_fast_writer.json");
		ofs << str;
		ofs.close();

		// 排版型
		str = swriter.write(value);
		ofs.open("example_styled_writer.json");
		ofs << str;
		ofs.close();
	}


	{
		int nRetCode = 0;  


		//1.从字符串解析json  
		const char* str = "{\"uploadid\": \"UP000000\",\"code\": 100,
		                                                      \"msg\": \"\",\"files\": \"\"}";  

		Json::Reader reader;  
		Json::Value root;  
		if (reader.parse(str, root))  
		{  
			printf("--------------从字符串读取JSON---------------\n");  
			std::string upload_id = root["uploadid"].asString();  // upload_id = "UP000000"    
			int code = root["code"].asInt();                      // code = 100   

			printf("upload_id : %s\ncode : %d \n", upload_id.c_str(), code);  
		} 


		// 2. 向文件写入json 
		string sTempPath = "test_json.json";  
		WriteJsonData(sTempPath.c_str());

	}

	return 0;
}
{"encoding" : "UTF-8","plug-ins" : ["python","c++","ruby"],
                            "indent" : { "length" : 3, "use_space": true}}
//////////////////////////////////////////////////////////////////////////
UTF-8
python c++ ruby
python c++ ruby
3 true
3 true
UTF-8
python
3
--------------从字符串读取JSON---------------
upload_id : UP000000
code : 100
--------------------------------------------
{
   "adviceOpt" : [ "000", "001", "002" ],
   "keylist" : [
      {
         "keyBathNumber" : "1",
         "keyIdx" : "01",
         "keyValue" : "1111111111"
      },
      {
         "keyBathNumber" : "2",
         "keyIdx" : "02",
         "keyValue" : "2222222222"
      }
   ],
   "retCode" : "0000",
   "retMsg" : "成功"
}
------------------------------------------------
{
   "adviceOpt" : [ "000", "001", "003", "002" ],
   "keylist" : [
      {
         "keyBathNumber" : "1",
         "keyIdx" : "01",
         "keyValue" : "1111111111"
      },
      {
         "keyBathNumber" : "2",
         "keyIdx" : "33",
         "keyValue" : "333333333"
      }
   ],
   "retCode" : "0000",
   "retMsg" : "失败"
}
------------------------------------------------

判断key是否存在

bool Json::Value::isMember ( const char * key) const

Return true if the object has a member named key.

Note
    'key' must be null-terminated. 

bool Json::Value::isMember ( const std::string &  key) const
bool Json::Value::isMember ( const char* key, const char * end ) const
// print "encoding is a member"
if(root.isMember("encoding")){
    std::cout<<"encoding is a member"<

判断是否为null的成员函数

bool Json::Value::isNull ( ) const

if(root["tab"].isNull()){
    std::cout << "isNull" <

另外值得强调的是,Json::Value和C++中的map有一个共同的特点,就是当你尝试访问一个不存在的 key 时,会自动生成这样一个key-value默认为null的值对。也就是说

root["anything-not-exist"].isNull(); //false
root.isMember("anything-not-exist"); //true

// test
if (!root["aaa"].isNull()){
	cout << "aaa is null" << endl;
}else{
	cout << "aaa is not null" << endl;
}

if (root.isMember("aaa")){
	cout << "root has aaa" << endl;
}
else{
	cout << "root has not aaa" << endl;
}

// result
aaa is not null
root has aaa

所以注意: 1,先用 isMember( ) 2,再用 isNull( )

得到所有的key

typedef std::vector Json::Value::Members

Value::Members Json::Value::getMemberNames ( ) const

Return a list of the member names.

If null, return an empty list.

Precondition
    type() is objectValue or nullValue 

Postcondition
    if type() was nullValue, it remains nullValue 

可以看到Json::Value::Members实际上就是一个值为string的vector,通过getMemberNames得到所有的key。

删除成员

Value Json::Value::removeMember( const char* key)   

Remove and return the named member.
Do nothing if it did not exist.

Returns
    the removed Value, or null. 

Precondition
    type() is objectValue or nullValue 

Postcondition
    type() is unchanged 

Value Json::Value::removeMember( const std::string & key)   

bool Json::Value::removeMember( std::string const &key, Value *removed)         

Remove the named map member.
Update 'removed' iff removed.

Parameters
    key may contain embedded nulls.

Returns
    true iff removed (no exceptions) 

参考:
  1. https://blog.csdn.net/yc461515457/article/details/52749575
  2. http://open-source-parsers.github.io/jsoncpp-docs/doxygen/index.html

你可能感兴趣的:(Jsoncpp)