c++使用JsonCpp(转载)
原文地址:C++ jsoncpp学习笔记-CSDN博客
一、json基础
1.1 json
JSON是JavaScript Object Notation的缩写,它是一种数据交换格式,即一种与开发语言无关的、轻量级的数据存储格式。 JSON 比 XML 更小、更快,更易解析。
优点:易于人的阅读和编写,易于程序解析与生产。
JSON基于两种结构:
object: “名称/值”对的集合(A collection of name/value pairs),它被理解为对象(object)。
array: 值的有序列表(An ordered list of values)。在大部分语言中,它被实现为数组(array),矢量(vector),列表(list),序列(sequence)
1.2 json 的形式
数据结构:Object、Array
基本类型:string,number,true,false,null
(1)对象(object):首先一个花括号{},整个代表一个对象,同时里面是一种Key-Value的存储形式,它还有不同的数据类型来区分。
对象是一个无序的“‘名称/值’对”集合。一个对象以“{”(左括号)开始,“}”(右括号)结束。每个“名称”后跟一个“:”(冒号);“‘名称/值’ 对”之间使用“,”(逗号)分隔。
Object格式:
{key:value,key:value...}
key:string类型
value:任何基本类型或数据结构,比如object,array,string,number,true/false,null等。
如:
{ "name" : "tocy", "age" : 1000 }
(2)数组(Array)
数组(array) 是值(value)的有序集合。一个数组以“[”(左中括号)开始,“]”(右中括号)结束。值之间使用“,”(逗号)分隔。
使用方括号保存数组,数组值使用 ,(逗号)分割。
[{"name":"tocy"}, {"age":1000}, {"domain":"cn"}] [1, "ts", true, {"key":45}]
(3)值(value) 可以是双引号括起来的字符串(string)、数值(number)、true
、false
、 null
、对象(object)或者数组(array),这些结构可以嵌套。
- 数字(整数或浮点数)
- 字符串(在双引号中)
- 逻辑值(true 或 false)
- 数组(在方括号中)
- 对象(在花括号中)
- null
举例:
{ "book": [ { "id":"01", "language": "Java", "edition": "third", "author": "Herbert Schildt" }, { "id":"07", "language": "C++", "edition": "second" "author": "E.Balagurusamy" }] }
二、jsoncpp
2.1 jsoncpp
Json::Value 可以表示里所有的类型,比如int,string,object,array等。
Json::Reader 将json文件流或字符串解析到Json::Value, 主要函数有Parse。
Json::Writer 与Json::Reader相反,将Json::Value转化成字符串流,注意它的两个子类:Json::FastWriter和Json::StyleWriter,分别输出不带格式的json和带格式的json。
Json::Value root; Json::FastWriter writer; string name = "abcd"; root["name"] = name; root["number"] = "2010014357"; root["address"] = "xxxx"; root["age"] = 100; string data= writer.write(root); //need #include <fstream> cout<<"data:\n"<<data<<endl;
2.2 串解析json
2.2.1 从字符串解析json
int ParseJsonFromString() { const char* str = "{\"uploadid\": \"UP000000\",\"code\": 100,\"msg\": \"\",\"files\": \"\"}"; Json::Reader reader; Json::Value root; if (reader.parse(str, root)) // reader将Json字符串解析到root,root将包含Json里所有子元素 { std::string upload_id = root["uploadid"].asString(); // 访问节点,upload_id = "UP000000" int code = root["code"].asInt(); // 访问节点,code = 100 } return 0; }
2.2.2 从文件解析json
{ "uploadid": "UP000000", "code": "0", "msg": "", "files": [ { "code": "0", "msg": "", "filename": "1D_16-35_1.jpg", "filesize": "196690", "width": "1024", "height": "682", "images": [ { "url": "fmn061/20111118", "type": "large", "width": "720", "height": "479" }, { "url": "fmn061/20111118", "type": "main", "width": "200", "height": "133" } ] } ] }
int ParseJsonFromFile(const char* filename) { // 解析json用Json::Reader Json::Reader reader; // Json::Value是一种很重要的类型,可以代表任意类型。如int, string, object, array... Json::Value root; std::ifstream is; is.open (filename, std::ios::binary ); if (reader.parse(is, root)) { std::string code; if (!root["files"].isNull()) // 访问节点,Access an object value by name, create a null member if it does not exist. code = root["uploadid"].asString(); // 访问节点,Return the member named key if it exist, defaultValue otherwise. code = root.get("uploadid", "null").asString(); // 得到"files"的数组个数 int file_size = root["files"].size(); // 遍历数组 for(int i = 0; i < file_size; ++i) { Json::Value val_image = root["files"][i]["images"]; int image_size = val_image.size(); for(int j = 0; j < image_size; ++j) { std::string type = val_image[j]["type"].asString(); std::string url = val_image[j]["url"].asString(); } } } is.close(); return 0; }
遍历array时,可以使用for-auto 的形式
for(auto ) root["files"]
2.3 插入json
Json::Value arrayObj; // 构建对象 arrayObj["name"] = "computer"; arrayObj["brand"] = "dell"; //添加一个新的子节点 Json::Value new_item; new_item["date"] = "2021-06-28"; new_item["time"] = "22:30:36"; arrayObj["creation date"] = new_item;
{ "name" : "computer", "brand" : "dell", "creation date": { "date" = "2021-06-28", "time" = "22:30:36" } }
构造json数组
#include "json/json.h" #include <fstream> #include <iostream> using namespace std; int main() { Json::Value root; Json::FastWriter writer; Json::Value person; person["name"] = "hello world1"; person["age"] = 100; root.append(person); person["name"] = "hello world2"; person["age"] = 200; root.append(person); string data= writer.write(root); cout<<data<<endl; cout<<root.toStyledString()<<endl; return 0; }
[ { "age" : 100, "name" : "hello world1", } { "age" : 200, "name" : "hello world2", } ]
2.4 输出json
// 转换为字符串(带格式) std::string out = root.toStyledString(); // 输出无格式json字符串 Json::FastWriter writer; std::string out2 = writer.write(root);
2.5 判断某个字段是否存在
Json::value.isMember("字段名")
2.6 删除数组中的元素
最近在使用jsoncpp 的过程中要删除某个数组元素,找了半天没有合适的解决方案,翻看最新版jsoncpp的源码时发现jsoncpp已经写出了删除数组元素的函数removeIndex,详细用法如下:
Json::Value root;
Json::Value delete;
root.removeIndex(num,&delete);
参数说明: num为要删除的数组元素的下标,delete用来存储删除的元素(不需要的话可以不用管),原json对象删除指定的元素后还存储在root里面。
参考文献:
【1】c++ json详解: https://www.cnblogs.com/yelongsan/p/4134384.html
【2】JSON:https://www.liaoxuefeng.com/wiki/1022910821149312/1023021554858080
【3】json介绍:http://www.json.org.cn/
【4】json 教程:https://www.w3cschool.cn/json/wj5z1h7t.html
【5】jsoncpp源码:https://github.com/open-source-parsers/jsoncpp
【6】json简介及jsoncpp 用法:https://www.cnblogs.com/tocy/p/json-intro_jsoncpp-lib.html
1.下载JsonCpp
c++json库(jsoncpp)简单使用(包含下载使用方法,中文错误解决方案)_json库c++_picksan的博客-CSDN博客
github地址:https://github.com/open-source-parsers/jsoncpp
可以到csdn链接到gitcode下载
2.从下载的文件夹中运行amalgamate.py,目的是生成 jsoncpp.cpp json.h json-forwards.h
运行amalgamate.py需要安装python环境
3.把得到的这3个文件加入到VC的项目中一起编译,需要设置jsoncpp.cpp不要预编译头
引用json.h #include "dist/json/json.h"
即可使用jsoncpp中的类了
Json::Value Json::Reader Json::Writer