C++操作.json文件的超详细新手教程

发布时间:2022-8-12 09:19

最近因为项目原因需要解析JSON格式数据,所以这篇文章主要给大家介绍了关于C++操作.json文件的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下!

1.JSON简介

1.1 什么是JSON:

JSON是一种纯字符串形式的数据,它本身不提供任何方法(函数),非常适合在网络中进行传输。JavaScript、PHP、Java、Python、C++等编程语言都内置了处理JSON数据的方法。

JSON 是基于 JavaScript(Standard ECMA-262 3rd Edition - December 1999)的一个子集,是一种开放的、轻量级的数据交换格式,采用独立于编程语言的文本格式来存储和表示数据,易于程序员阅读与编写,同时也易于计算机解析和生成,通常用于在 Web 客户端(浏览器)与 Web 服务器端之间传递数据。

在JSON中,使用一下两种方式表示数据:

object(对象):键/值对(名称/值)的集合,使用花括号{}定义。在每个键/值对中,以键开头,后跟一个冒号,最后是值。多个键/值对之间使用逗号分隔,例如"name":"FilterWindow","paramtype":"0"。Array(数组):值的有序集合,使用方括号[]定义,数组中每个值之间使用逗号进行分隔。

下面展示一个简单的JSON数据:

{
	"name" : "FilterWindow",
	"paramtype" : "0",
	"range" : 
	{
		"max" : 99,
		"min" : 3
	},
	"required" : true,
	"title" : "滤波窗口大小",
	"type" : "int",
	"value" : 51
	"tempValue" : 
	[
		"不生成" : 1,
		"生成" : 0
	],
}

1.2 JSON的优缺点:

优点:

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

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

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

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

缺点:

只有一种数字类型:JSON中只能支持IEEE-754双精度浮点格式,因此我们无法使用JSON来存储许多编程语言中多样化的数字类型;

没有日期类型:在JSON中我们只能通过日期的字符串(例如:1970-01-01)或者时间戳(例如:1632366361)来表示日期;

没有注释:在JSON中无法添加注释;

冗长:虽然JSON比XML更加简洁,但它不是最简洁的数据交换格式,对于数据量庞大或用途特殊的服务,我们需要更加高效的数据格式。

1.3 JSON的存储:

JSON数据可以存储在.json格式的文件中(与.txt格式类似,都属于纯文本文件),也可以将JSON数据以字符串的形式存储在数据库、Cookie、Session中。要使用存储好的JSON数据也非常简单,不同的编程语言中提供了不同的方法来检索和解析JSON数据,今天我们的重点就是使用C++来操作.json文件。而C++主要使用jsoncpp这个跨平台的开源库来实现对.json文件的各类操作。

2.jsoncpp库介绍

2.1 jsoncpp库的配置使用:

这里我就不按照网上常规的方式来介绍了,常规的方法无非是关于下载jsoncpp库,然后使用Windows编译(vs2015),最后整理出include及lib来使用jsoncpp库。我这里是整理好的,是直接把include里的所有文件集合成json.h以及json.cpp。用的时候直接把这些文件包含进自己的项目一起编译即可。

C++操作.json文件的超详细新手教程

2.2 jsoncpp库内部构成:

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

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

enum ValueType
   {
  nullValue = 0, ///< 'null' value
  intValue,  ///< signed integer value
  uintValue, ///< unsigned integer value
  realValue, ///< double value
  stringValue,   ///< UTF-8 string value
  booleanValue,  ///< bool value
  arrayValue,///< array value (ordered list)
  objectValue///< object value (collection of name/value pairs).
   };

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;
5、【将Value对象进行相应的类型转换】
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 );
8、【获取满足相应条件的Value】
Value get( UInt index, const Value &defaultValue ) const;
Value get( const std::string &key,const Value &defaultValue ) const;
Members getMemberNames() const;
9、【删除满足相应条件的Value】
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;

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

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

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

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

3.json文件读取(例)

3.1 json文件:

{
  "face": [
{
  "attribute": {
"age": {
  "range": 5,
  "value": 35
},
"gender": {
  "confidence": 99.9995,
  "value": "Male"
},
"glass": {
  "confidence": 98.8995,
  "value": "None"
},
"pose": {
  "pitch_angle": {
"value": -0.000006
  },
  "roll_angle": {
"value": 5.32508
  },
  "yaw_angle": {
"value": -22.432627
  }
},
"race": {
  "confidence": 98.62100000000001,
  "value": "Asian"
},
"smiling": {
  "value": 97.3715
}
  },
  "face_id": "2f60c56506b691c0384e2694fed1c819",
  "position": {
"center": {
  "x": 51.463415,
  "y": 25.121951
},
"eye_left": {
  "x": 46.197561,
  "y": 20.161
},
"eye_right": {
  "x": 56.724146,
  "y": 21.142171
},
"height": 22.926829,
"mouth_left": {
  "x": 45.610732,
  "y": 30.399024
},
"mouth_right": {
  "x": 56.01561,
  "y": 31.734146
},
"nose": {
  "x": 49.063659,
  "y": 27.171951
},
"width": 22.926829
  },
  "tag": ""
}
  ],
  "img_height": 410,
  "img_id": "84c20011223acd4efa0b5aa13fc2146d",
  "img_width": 410,
  "session_id": "42c5db376fdc4da9855d0135b5e414e2",
  "url": "http://www.faceplusplus.com.cn/wp-content/themes/faceplusplus/assets/img/demo/16.jpg?v=2"
}

3.2 源码:

#include<iostream>
#include<fstream>
#include<assert.h>
#include "json.h"

using namespace std;

int main()
{
	Json::Reader reader;
	Json::Value root;

	ifstream is;  

	is.open("face.json", ios::binary);

	if (reader.parse(is, root))
	{
		Json::StyledWriter sw; //缩进输出
		cout << "缩进输出" << endl;
		cout << sw.write(root) << endl << endl;
	}
	return 0;
}

3.3 结果图:

C++操作.json文件的超详细新手教程