C++ 操作 json 文件(使用jsoncpp)

前人栽树,后人乘凉,声明部分引用自:

  1. C++ 之 C++ 操作 json 文件(C++读写json文件)及jsoncpp配置详解
  2. C++构造和解析Json
  3. C++中JSON的使用详解

一.介绍

1.什么是Json?

JSON是一种轻量级的数据交互格式,易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率,实际项目中经常用到,相比xml有很多优点。

2. Json与其他数据存储方式比较

为什么要用json文件呢?

我们最常使用的存储数据的方式有很多,比如利用txt文件存,利用xml存,利用word存,利用Excel存,如果我们要求比较高,还可以使用数据库存。

相对于txt,word来说,json格式更加明确,获取重要信息非常方便。

相对于xml来说,json格式更加简洁,存储同样的文件,花费的内存更小。

相对于Excel来说,json更适合存储字符类文件。Excel相当于比较简单的数据库了。

相对于数据库来说,json更加方便,数据库我们还需要做一些设置,安装一些软件。json可以直接使用。

3. 内部构成

jsoncpp 主要包含三个class:Value、Reader、Writer。注意Json::Value 只能处理 ANSI 类型的字符串,如果 C++ 程序是用 Unicode 编码的,最好加一个 Adapt 类来适配。

value的基本类型有:字符串、数字、true/false、null。

------------------------------- Json内部类和方法 --------------------------------

Reader<是用于读取的,说的确切点,是用于将字符串转换为 Json::Value 对象的>

   【构造函数】
    1、Reader();
   【拷贝构造函数】
    2、Reader( const Features &features );
   【将字符串或者输入流转换为JSON的Value对象】
   【下边是相应的parse的重载函数】
    3、bool parse( const std::string &document, Value &root,bool collectComments = true );
    4、bool parse( const char *beginDoc, const char *endDoc, 

                   Value &root,bool collectComments = true         

    5、bool parse( std::istream &is,Value &root,bool collectComments = true );
    6、std::string getFormatedErrorMessages() const;

Value:<是jsoncpp 中最基本、最重要的类,用于表示各种类型的对象,jsoncpp 支持的对象类型可见 Json::ValueType 枚举值; Value类的对象代表一个JSON值,既可以代表一个文档,也可以代表 文档中一个值。如同JSON中定义的“值”一样,Value是递归的.

    【构造函数】
     1、Value( ValueType type = nullValue );
      Value( Int value );
      Value( UInt value );
      Value( double value );
      Value( const char *value );
      Value( const char *beginValue, const char *endValue );
    【拷贝构造函数】
     2、Value( const StaticString &value );
      Value( const std::string &value );
      Value( const Value &other );
    【相同类型的比较、交换、类型的获取】
     3、void swap( Value &other );
      ValueType type() const;
      int compare( const Value &other );
    【相应的赋值运算符的重载函数】
     4、Value &operator=( const Value &other );
      bool operator <( const Value &other ) const;
      bool operator <=( const Value &other ) const;
      bool operator >=( const Value &other ) const;
      bool operator >( const Value &other ) const;
      bool operator ==( const Value &other ) const;
      bool operator !=( const Value &other ) const;
      bool operator!() const;
      Value &operator[]( UInt index );
      const Value &operator[]( UInt index ) const;
    【将Value对象进行相应的类型转换】
     5、const char *asCString() const;
      std::string asString() const; 
      const char *asCString() const;
      std::string asString() const;
      Int asInt() const;
      UInt asUInt() const;
      double asDouble() const;
    【相应的判断函数】
     6、bool isNull() const;
      bool isBool() const;
      bool isInt() const;
      bool isUInt() const;
      bool isIntegral() const;
      bool isDouble() const;
      bool isNumeric() const;
      bool isString() const;
      bool isArray() const;
      bool isObject() const;
      bool isConvertibleTo( ValueType other ) const;
      bool isValidIndex( UInt index ) const;
      bool isMember( const char *key ) const;
      bool isMember( const std::string &key ) const;
    【清除和扩容函数】
     7、void clear();
     void resize( UInt size );
    【获取满足相应条件的Value】
     8、Value get( UInt index, const Value &defaultValue ) const;
     Value get( const std::string &key,const Value &defaultValue ) const;
     Members getMemberNames() const;
    【删除满足相应条件的Value】
     9、Value removeMember( const char* key );
      Value removeMember( const std::string &key );
     10、void setComment( const char *comment,CommentPlacement placement );
      void setComment( const std::string &comment,CommentPlacement placement );
      bool hasComment( CommentPlacement placement ) const;
      std::string getComment( CommentPlacement placement ) const;
      std::string toStyledString()const;

Writer:<类是一个纯虚类,并不能直接使用。在此我们使用 Json::Writer 的子类(派生类):
Json::FastWriter、Json::StyledWriter、Json::StyledStreamWriter。顾名思义,用 Json::FastWriter 来处理 json 应该是最快的;负责将内存中的Value对象转换成JSON文档,输出到文件或者是字符串中.

     【FastWriter】
      1、FastWriter();
      virtual ~FastWriter(){}
      void enableYAMLCompatibility();
      virtual std::string write( const Value &root );
     【StyledWriter】
      2、StyledWriter();
      virtual ~StyledWriter(){}
      virtual std::string write( const Value &root );

二. 使用

1. jsoncpp库配置

json解析选用jsoncpp作为第三方库,使用广泛,C++一般首选。

可以自行网上下载源码,生成lib或dll库导入项目使用;
也可以点击这里下载:jsoncpp.rar
(解压,里面包含lib库和头文件夹,分别导入你项目的include和lib文件夹下即可)。

2. C++从字符串读取Json

首先需要在.cpp文件头部引入

 #include<json.h>

以及配置项里链接器加入:

jsoncpp.lib     // 名字可能有差异

即可。

1. 单层结构json串

设定如下样式:

{
    "name" : "zhangsan",
    "age" : "25",
    "sex" : "man"
}

读取代码如下:


void readStrJson()
{
	//字符串  
	const char* str =
		"{\"name\":\"zhangsan\",\"age\":\"25\",\"sex\":\"man\"}";
 
 
	Json::Reader reader;
	Json::Value root;
 
	//从字符串中读取数据  
	if (reader.parse(str, root))  // 如果解析成功
	{
		string name = root["name"].asString();
		int age = root["nomen"].asInt();
		string sex = root["sex"].asString();
		cout << name + "," << age << "," << sex <<  endl;
	}
}

2. 复杂结构json串(多层)

设定如下样式:


{
    "name":"zhangsan",
    "Info":{
        "id":"001",
        "class":"03",
        "teacher":"Qinjiang"
    },
    "Hobby": ["sing","rap","basketball"],
    "Scores":[{
		"Chinese": "80"
	},{
		"Chinese": "90"
	}]
}

读取代码如下:


void readStrProJson()
{
	string strValue = "{\"name\":\"zhangsan\",\"Info\":{\"id\":\"001\",\"class\":\"03\",\"teacher\":\"Qinjiang\"},\"Hobby\":[\"sing\",\"rap\",\"basketball\"],\"Scores\":[{\"Chinese\":\"80\"}, {\"Chinese\": \"90\"}]}";
	Json::Reader reader;
	Json::Value value;
	if (reader.parse(strValue, value))
	{
		// name
		string name = value["name"].asString();
		cout << name << endl;
		// info
		string id = value["Info"]["id"].asString();
		cout << id << endl;
		string sclass = value["Info"]["class"].asString();
		cout << sclass << endl;
		string teacher = value["Info"]["teacher"].asString();
		cout << teacher << endl;
		// hobby
		for (unsigned int i = 0; i < value["Hobby"].size(); i++)
		{
			string ach = value["Hobby"][i].asString();
			cout << ach << '\t';
		}
		// scores
		JSON::Value &result = value["Scores"];
		for (int i=0; i<result.size(); i++)
		{
			string score = result[i]["Chinese"].asString();
			cout << score << endl;
		}
	}
}

假如Scores数组里不止一个{},key值相同时,直接如上遍历输出;如果多个{}且内部key彼此({}和{})不同时可以加if条件输出不同的值。

3. C++从文件构造/解析json

以下面为例:


{
   "age" : 21,
   "friends" : {
      "friend_age" : 21,
      "friend_name" : "ZhaoWuxian",
      "friend_sex" : "man"
   },
   "hobby" : [ "sing", "run", "Tai Chi" ],
   "name" : "shuiyixin",
   "sex" : "man"
}

读取代码如下;


void readFileJson()
{
	Json::Reader reader;
	Json::Value root;
 
	//从文件中读取,保证当前文件有demo.json文件  
	ifstream in("demo.json", ios::binary);
 
	if (!in.is_open())
	{
		cout << "Error opening file\n";
		return;
	}
 
	if (reader.parse(in, root))
	{
		//读取根节点信息  
		string name = root["name"].asString();
		int age = root["age"].asInt();
		string sex = root["sex"].asString();
 
		cout << "My name is " << name << endl;
		cout << "I'm " << age << " years old" << endl;
		cout << "I'm a " << sex << endl;
 
		//读取子节点信息  
		string friend_name = root["friends"]["friend_name"].asString();
		int friend_age = root["friends"]["friend_age"].asInt();
		string friend_sex = root["friends"]["friend_sex"].asString();
 
		cout << "My friend's name is " << friend_name << endl;
		cout << "My friend's sex is "<<friend_sex << endl;
		cout << "My friend is " << friend_age << " years old" << endl;
 
		//读取数组信息  
		cout << "Here's my hobby:" << endl;
		for (unsigned int i = 0; i < root["hobby"].size(); i++)
		{
			string ach = root["hobby"][i].asString();
			cout << ach << '\t';
		}
		cout << endl;
 
		cout << "Reading Complete!" << endl;
	}
	else
	{
		cout << "parse error\n" << endl;
	}
 
	in.close();
}

4. C++写入json文件

如下:


{
   "age" : 21,
   "friends" : {
      "friend_age" : 21,
      "friend_name" : "ZhaoWuxian",
      "friend_sex" : "man"
   },
   "hobby" : [ "sing", "run", "Tai Chi" ],
   "name" : "shuiyixin",
   "sex" : "man"
}

写入代码如下:


void writeFileJson()
{
	//根节点  
	Json::Value root;
 
	//根节点属性  
	root["name"] = Json::Value("shuiyixin");
	root["age"] = Json::Value(21);
	root["sex"] = Json::Value("man");
 
	//子节点  
	Json::Value friends;
 
	//子节点属性  
	friends["friend_name"] = Json::Value("ZhaoWuxian");
	friends["friend_age"] = Json::Value(21);
	friends["friend_sex"] = Json::Value("man");
 
	//子节点挂到根节点上  
	root["friends"] = Json::Value(friends);
 
	//数组形式  
	root["hobby"].append("sing");
	root["hobby"].append("run");
	root["hobby"].append("Tai Chi");
 
	//直接输出  
	//cout << "FastWriter:" << endl;
	//Json::FastWriter fw;
	//cout << fw.write(root) << endl << endl;
 
	//缩进输出  
	cout << "StyledWriter:" << endl;
	Json::StyledWriter sw;
	cout << sw.write(root) << endl << endl;
 
	//输出到文件  
	ofstream os;
	os.open("demo.json", std::ios::out | std::ios::app);
	if (!os.is_open())
		cout << "error:can not find or create the file which named \" demo.json\"." << endl;
	os << sw.write(root);
	os.close();
 
}
上一篇:jsoncpp转换类


下一篇:k8s二进制安装-7,安装kube-scheduer