下载对应的版本
下载: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.json
if(!reader.parse(ifs, root)){
// fail to parse
}
else{
// success
std::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))
{
// 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"<<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 ( ) const
if(root["tab"].isNull()){
std::cout << "isNull" <<std::endl;//print isNull
}
if(root.isMember("tab-length"))
{
//true
if(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 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
}
另外值得强调的是,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::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)