Jsoncpp如何使用及样例

2024-05-25 08:58
文章标签 使用 jsoncpp 及样

本文主要是介绍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<ST_Key> keyList;
};struct ST_KeySync_Ret
{std::string retCode;std::string retMsg;std::vector<ST_KeyCurVer> 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<std::string,std::string>::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.jsonif(!reader.parse(ifs, root)){// fail to parse
}
else{// successstd::cout<<root["encoding"].asString()<<endl;std::cout<<root["indent"]["length"].asInt()<<endl;
}
使用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 <iostream>
#include <string>
#include <fstream>#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)){// encodingcout << value["encoding"].asString() << endl;// 关于plug-ins// 方法1const Json::Value arrayObj1 = value["plug-ins"];for (int i = 0; i < arrayObj1.size(); ++i){cout << arrayObj1[i].asString() << " ";}cout << endl;// 方法2cout << value["plug-ins"][0].asString() << " ";cout << value["plug-ins"][1].asString() << " ";cout << value["plug-ins"][2].asString() << " ";cout << endl;// 关于indent// 方法1const Json::Value arrayObj2 = value["indent"];cout << arrayObj2["length"].asString() << " ";cout << arrayObj2["use_space"].asString() << " ";cout << endl;// 方法2cout << 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.jsonif(reader.parse(ifs, value)){// successcout << 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.jsonif(! reader.parse(ifs, value)){// parse failreturn 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) constReturn 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"<<std::endl;
}
else{std::cout<<"encoding is not a member"<<std::endl;
}// print "encode is not a member"
if(root.isMember("encode")){std::cout<<"encode is a member"<<std::endl;
}
else{std::cout<<"encode is not a member"<<std::endl;
}

判断是否为null的成员函数

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

另外值得强调的是,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<std::string> Json::Value::MembersValue::Members Json::Value::getMemberNames ( ) constReturn a list of the member names.If null, return an empty list.Preconditiontype() is objectValue or nullValue Postconditionif 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.Returnsthe removed Value, or null. Preconditiontype() is objectValue or nullValue Postconditiontype() 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.Parameterskey may contain embedded nulls.Returnstrue 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如何使用及样例的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1001052

相关文章

Java使用Curator进行ZooKeeper操作的详细教程

《Java使用Curator进行ZooKeeper操作的详细教程》ApacheCurator是一个基于ZooKeeper的Java客户端库,它极大地简化了使用ZooKeeper的开发工作,在分布式系统... 目录1、简述2、核心功能2.1 CuratorFramework2.2 Recipes3、示例实践3

springboot security使用jwt认证方式

《springbootsecurity使用jwt认证方式》:本文主要介绍springbootsecurity使用jwt认证方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录前言代码示例依赖定义mapper定义用户信息的实体beansecurity相关的类提供登录接口测试提供一

go中空接口的具体使用

《go中空接口的具体使用》空接口是一种特殊的接口类型,它不包含任何方法,本文主要介绍了go中空接口的具体使用,具有一定的参考价值,感兴趣的可以了解一下... 目录接口-空接口1. 什么是空接口?2. 如何使用空接口?第一,第二,第三,3. 空接口几个要注意的坑坑1:坑2:坑3:接口-空接口1. 什么是空接

springboot security快速使用示例详解

《springbootsecurity快速使用示例详解》:本文主要介绍springbootsecurity快速使用示例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝... 目录创www.chinasem.cn建spring boot项目生成脚手架配置依赖接口示例代码项目结构启用s

Python如何使用__slots__实现节省内存和性能优化

《Python如何使用__slots__实现节省内存和性能优化》你有想过,一个小小的__slots__能让你的Python类内存消耗直接减半吗,没错,今天咱们要聊的就是这个让人眼前一亮的技巧,感兴趣的... 目录背景:内存吃得满满的类__slots__:你的内存管理小助手举个大概的例子:看看效果如何?1.

java中使用POI生成Excel并导出过程

《java中使用POI生成Excel并导出过程》:本文主要介绍java中使用POI生成Excel并导出过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录需求说明及实现方式需求完成通用代码版本1版本2结果展示type参数为atype参数为b总结注:本文章中代码均为

Spring Boot3虚拟线程的使用步骤详解

《SpringBoot3虚拟线程的使用步骤详解》虚拟线程是Java19中引入的一个新特性,旨在通过简化线程管理来提升应用程序的并发性能,:本文主要介绍SpringBoot3虚拟线程的使用步骤,... 目录问题根源分析解决方案验证验证实验实验1:未启用keep-alive实验2:启用keep-alive扩展建

使用Java实现通用树形结构构建工具类

《使用Java实现通用树形结构构建工具类》这篇文章主要为大家详细介绍了如何使用Java实现通用树形结构构建工具类,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录完整代码一、设计思想与核心功能二、核心实现原理1. 数据结构准备阶段2. 循环依赖检测算法3. 树形结构构建4. 搜索子

GORM中Model和Table的区别及使用

《GORM中Model和Table的区别及使用》Model和Table是两种与数据库表交互的核心方法,但它们的用途和行为存在著差异,本文主要介绍了GORM中Model和Table的区别及使用,具有一... 目录1. Model 的作用与特点1.1 核心用途1.2 行为特点1.3 示例China编程代码2. Tab

SpringBoot使用OkHttp完成高效网络请求详解

《SpringBoot使用OkHttp完成高效网络请求详解》OkHttp是一个高效的HTTP客户端,支持同步和异步请求,且具备自动处理cookie、缓存和连接池等高级功能,下面我们来看看SpringB... 目录一、OkHttp 简介二、在 Spring Boot 中集成 OkHttp三、封装 OkHttp