在处理json数据时,数据的序列化及反序列化是经常要使用的方法,下面详细介绍些jsoncpp关于序列化及反序列话的方法。
Json::Value node;
Json::Reader reader;
Json::FastWriter writer;
std::string str = "{\"name\":\"yang\", \"age\":10}";
//反序列化
reader.parse(str, node);//反序列化,将字符串转化为json格式的数据
//序列化
std::string str1 = node["name"].asString();//只能序列化json的object,不能带key值一起序列化。
std::string str1 = node.asString();//会出现段错误
str = node.toStyledString(); //序列化为带格式字符串,序列化整个接送对象
std::string str2 = writer.write(node);//序列化为不带格式的字符串
/*
注:toStyledString的序列化时带格式的字符换,如上面的str = node.toStyledString()输出的是:
{
"age" : 10,
"name" : "yang"
}
转化为字符字符串为:"{\n\"age\":10, \n\"name\":\"yang\"\n}"
str2 = writer.write(node);序列化的字符串就不带格式,序列化的结果为:{"age":10,"name":"yang"}
而str1 = node["name"].asString();输出不带格式的字符串,str1 = yang;
除了asString字符串格式的序列化,还有其他类型的序列化输出:
str1 = node["name"].asInt(); //序列化为int类型
str1 = node["name"].asFloat(); //序列化为浮点型
str1 = node["name"].asUint64(); //序列化为uint64_t类型
str1 = node["name"].asCString(); //序列化为const char *类型
str1 = node["name"].asString(); //序列化为std::string 类型
等;
*/
std::string jsonStr = "\"name\":\"yang\", \"age\":20";
Json::Reader reader;
Json::Value value;
reader.parse(jsonStr,value);
Json::Value::Members member = value.getMemberNames();
for(Json::Value::Members::iterator iter = member.begin(); iter != member.end(); ++iter)
{
//获得key
cout << (*iter) << endl;
//获取val
std::cout << value[*iter] << std::endl;
}
//打印
name
age
在处理json数据时,经常会需要确定json object的值类型,从而进行对应的处理,下面说一下json值怎么创建与判断!
//创建json某类型的值
Json::Value array = Json::Value(Json::arrayValue)//创建数组类型的obj
//除了数组类型还有以下类型:
Json::arrayValue //数组
Json::intValue //符号整型
Json::uintValue //无符号整型
Json::nullValue //空类型
Json::objectValue //obj类型
Json::booleanValue //bool类型
Json::stringValue //string类型
//查询json某个key的值的类型,有json数据:Json::Value obj = "test" : {"age":10,"name":"yang"},加入不知道age值的类型,如下方式确定
//test值的类型就是obj类型接下来判断age
//方法1:
obj["test"]["age"].type()//获取age的值类型然后和json类型比较
if(obj["test"]["age"].type() == Json::booleanValue)
{
std::cout << "age value type is bool" << std::endl;
}
//方法2
if(obj["test"]["age"].isInt())
{
std::cout << "age type is int " << std::endl;
}
//有json数据:
Json::Value root = "{\"name\":\"yang\",\"age\":10}"
//修改age
root["age"] = 20;
//删除name
Json::Value root;
Json::Reader reader;
std::string str = "{\"name\":\"yang\",\"age\":10}";
reader.parse(str, root);//反序列化
std::cout << root.toStyledString() << std::endl;//打印字符串
Json::Value del;
root.removeMember("name", &del);//删除成员
//或者 root.removeMember("name");
std::cout << root.toStyledString() << std::endl;
Json::Value root;
Json::Value mem1;
mem1["name"] = "yang";
root.append(mem1);//添加数组成员
Json::Value mem2;
mem2["age"] = 10;
root.append(mem2);
std::cout << root.toTypeString() << std::endl;
//结果
test
[
{
"name" : "yang"
},
{
"age" : 10,
}
]
test
[
{
"name" : "yang"
},
{
"name" : "zhao"
}
]
//以上面test数组为例,访问age数组:
int val = test[1]["age"];
//因此可以这样遍历数组
for(int i = 0; i < test.size(); i++)
{
std::cout << test[i]["name"].asString() << std::endl;
}
test
[
{
"name" : "yang",
"age":10
},
{
"name" : "zhao",
"age":20
}
]
//删除第一个元素
test.removeIndex(0,nullptr);
//读文件
std::ifstream ifs;
ifs.open(file);
if(ifs.is_open()){
// 创建一个reader,将文件流解析成json对象root
Json::Reader jsonReader;
if(!jsonReader.parse(ifs, json, false)) {
printf("jsonReader parse fail. file: %s\n", file.c_str());
ifs.close();
return -1;
}
ifs.close();
Json::StreamWriterBuilder builder;
const std::string json_string = Json::writeString(builder, json);
// 打印
// std::cout << "\nload config file [" << file << "] :\n"<< json << std::endl;
printf("load config file %s: \n%s\n", file.c_str(), json_string.c_str());
return 0;
}else{
printf("can not load config file: %s\n", file.c_str());
}
Json::StreamWriterBuilder w_builder;
const std::unique_ptr writer(w_builder.newStreamWriter());
// 写入文件
std::ofstream ofs;
ofs.open(file);
if(ofs.is_open()){
writer->write(json, &ofs);
ofs.flush();
ofs.close();
return 0;
}
return -1;