Json

1: Json 简介

全名: java script object notation
是一种数据的格式, 和语言没有关系

Json作用

  • 组织数据, 进行网络之间的数据传输 -> 数据序列化(轻量级数据)
  • 写配置文件 -> 内存到磁盘或者磁盘到内存
  • 文本格式

2:环境配置

windows 下Json 数据格式的配置:

  • 项目中属性的配置:主要是:包含库目录(函数实现文件) 和 包含目录(头文件)
  • 把 Jsoncpp 的库文件和头文件插入到项目中。

在这里插入图片描述

2:链接静态库

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DacM2JWW-1583916530191)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200311112951341.png)]

3:选择的模式为路径: c++ / -> 代码生成 -> 多线程调试( _MTD)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qLpoVzNk-1583916530193)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200311113240308.png)]



或者:

windows 下使用VS编译jsoncpp

  • 在windows下 将 jsoncpp-0.10.7.tar.gz解压缩

  • 进入到解压目录jsoncpp-0.10.7, 在进入到子目录makefiles\msvc2010

  • 使用vs打开项目文件jsoncpp.sln

  • 编译该项目, 生成库文件

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YQbjbGBu-1583916530198)(F:/学习课程/项目一/课堂文件/day07/day07 - jsoncpp-秘钥协商/01-教学资料/assets/1567304880789.png)]

  • 生成的静态库存储目录jsoncpp-0.10.7\makefiles\msvc2010\Debug

  • 生成的静态库文件: lib_json.lib

  • 使用的准备工作:

    • 将静态库lib_json.lib拿出备用
    • 将库对应的头文件拿出, 头文件目录`jsoncpp-0.10.7\include\json


linux: Json 环境配置

2: Linux 下的安装和部署

  • 准备安装包

    • jsoncpp-0.10.7.tar.gz
    • scons-3.0.5.zip
  • 解压缩

    $ tar zxvf jsoncpp-0.10.7.tar.gz
    $ unzip scons-3.0.5.zip
    
  • 安装scons -> 进入 scons-3.0.5.zip 的解压目录

    # 要使用管理员权限执行该命令
    $ python setup.py install 
    
  • 安装 jsoncpp -> 进入 jsoncpp-0.10.7.tar.gz 的解压目录

    $ scons platform=linux-gcc 
    # 将生成的动态库/静态库拷贝到系统的库目录中, 需要管理员权限
    $ cp libs/linux-gcc-***/* /lib
    # 拷贝json的头文件到系统目录中, 需要管理员权限
    $ cp include/json/ /usr/include/ -r
    # 创建动态库的链接文件, 需要管理员权限
    ln -s /lib/libjson_linux-gcc-xxx_libmt.so /lib/libjson.so
    # 更新, 这样才能搜索到动态库 libjson.so。需要管理员权限
    $ ldconfig	# ubuntu需需要加sudo
    # 测试
    $ ./bin/linux-gcc-***/test_lib_json 
    Testing ValueTest/checkNormalizeFloatingPointStr: OK
    Testing ValueTest/memberCount: OK
    Testing ValueTest/objects: OK
    Testing ValueTest/arrays: OK
    ..................
    Testing BuilderTest/settings: OK
    Testing IteratorTest/distance: OK
    Testing IteratorTest/names: OK
    Testing IteratorTest/indexes: OK
    All 53 tests passed
    
  • 编译 c++ 测试文件: json-test.cpp

    g++ json-test.cpp -ljson -o json
    


3: 代码测试

#include <json/json.h>
#include <iostream>
#include <string>
#include  <fstream>

using namespace std;
using namespace Json;

void writeJson()
{
	Value root;
	root.append("不良人");
	root.append(1000);

	// 键值对的插入
	Value money;
	money["收入"] = 1000;
	money["支出"] = 200;
	root.append(money);

	// 数组的插入。
	Value name;
	name.append("张子凡");
	name.append("李星云");
	name.append("林轩");
	root.append(name);

	// 文字流的读取, 将Json 数据的格式进行转换。
	string str = root.toStyledString();
	ofstream ofs("不良人.json");
	ofs << str;
	ofs.close();
}

void readJson()
{
	ifstream ifs("不良人.json");
	Reader r;

	Value root;
	r.parse(ifs, root);

	// 按照一定的格式进行输出
	if (root.isArray()) {
		cout << "这是一个数组\n" << endl;
		for (unsigned int i = 0; i < root.size(); i++) {
			// 依次取出元素
			Value member = root[i];
			if (member.isInt()) {
				// 整形输出
				cout << member.asInt() << endl;
			}
			else if (member.isString()) {
				// 字符串输出
				cout << member.asString() << endl;
			}
			else if (member.isArray()) {
				// 定义数组进行输出
				for (unsigned int k = 0; k < member.size(); k++) {
					cout << member.get(k, NULL).asString() << endl;
				}
			}
			else if (member.isObject()) {
				// 定义是一个键值键值对时。
				// 如果是一个键值对,先取出key 值,在进行取出 value 
				Value::Members keys = member.getMemberNames();
				for (unsigned int j = 0; j < keys.size(); j++) {
					cout << keys[j] << ":" << member[keys[j]].asInt() << endl;
				}
			}
		}
	}
}

int main(int argv, char * argc) {
	writeJson();
	readJson();

	system("pause");
	return 0;
}

运行结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IWQe3kWE-1583916530205)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200311113451890.png)]



2:配置文件的书写

#include <iostream>
#include <json/json.h>
#include <fstream>
#include <string>

using namespace std;
using namespace Json;


void writeJson1() {
	Value root;
	Value object;
	object["Port"] = 9999;
	object["ServerID"] = "192.268.29";
	object["ClientID"] = "192.268.192";

	root.append(object);

	string str = root.toStyledString();
	ofstream ofs("config.json");
	ofs << str;
	ofs.close();		// 刷新缓冲区
}


void writeJson() {
	Value object;
	object["Port"] = 9999;
	object["ServerID"] = "192.268.29";
	object["ClientID"] = "192.268.192";

	string str = object.toStyledString();
	ofstream ofs("config.json");
	ofs << str;
	ofs.close();		// 刷新缓冲区
}
void readJson()
{
	// 解析 json 文件
	ifstream ifs("config.json");

	Reader r;
	Value root;
	r.parse(ifs, root);
	cout << root << endl;
	cout << endl;

	string ServerID = root["ServerID"].asString();
	cout << "serverID:" << ServerID << endl;

	unsigned int  Port = root["Port"].asInt();
	cout << "port:" <<Port << endl;

	string ClientID = root["ClientID"].asString();
	cout << "clientID:" << ClientID << endl;

}

int  main(int argv, char * argc)
{
	writeJson();
	readJson();
	system("pause");
	return 0;
}

writeJson1 中写入后代码的格式:

在这里插入图片描述

// 读取格式
if (root.isArray()) {
		cout << "这是一个数组" << endl;
		for (unsigned int i = 0; i < root.size(); i++) {
			Value member = root[i];
			if (member.isObject()) {
				for (unsigned int k = 0; k < member.size(); k++) {
					Value::Members keys = member.getMemberNames();
					cout << keys[k] << ":" << member[keys[k]].asString() << endl;
				}
			}
		}
	}

writeJSon 中写入后代码的格式:

在这里插入图片描述

string ServerID = root["ServerID"].asString();
	cout << "serverID:" << ServerID << endl;

	unsigned int  Port = root["Port"].asInt();
	cout << "port:" <<Port << endl;

	string ClientID = root["ClientID"].asString();
	cout << "clientID:" << ClientID << endl;


4: Json 相关知识

1: 常用的类

/*
	三个类:
		Value, Reader, FastWriter
		
	Value类:
		- 将json支持的数据类型进行了包装, 最终得到一种类型 -> Value类型
			- 整形, 浮点型, 布尔类型, 字符串, json数组, json对象
		- 判断Value对象中的原始数据类型
		- 类型转换功能, 将Value对象转换成功原始数据
		- 给对象/数组添加元素
		
	Reader类: 反序列化, 将json字符串 解析成 Value 类型 
	FastWriter类: 将Value对象中的数据序列化为字符串
*/

2: Jsoncpp 处理 Json数据

/*
	需要在内存中将json数组组织起来 -> 序列化为字符串
	1. 创建一个Value对象, 将数据添加到Value对象中
	2. 将Value对象序列化 -> 字符串 , 使用 FastWriter类
	3. 将字符串写入到文件中
*/

/*
	磁盘有一个json文件 (有一个josn字符串) -> 将字符串数据反序列化到到内存中
	1. 打开磁盘文件将json字符串读出
	2. 将字符串数据解析到 Value 中, 使用 Reader类
	3. 通过Value对象将Value中的数据依次读出
*/

3: Value类

枚举类型说明翻译
nullValue‘null’ value不表示任何数据,空值
intValuesigned integer value表示有符号整数
uintValueunsigned integer value表示无符号整数
realValuedouble value表示浮点数
stringValueUTF-8 string value表示utf8格式的字符串
booleanValuebool value表示布尔数
arrayValuearray value (ordered list)表示数组,即JSON串中的[]
objectValueobject value (collection of name/value pairs)表示键值对,即JSON串中的{}
  • 封装和修改数据
// 直接使用=赋值就可以了
Value& operator=(Value other);

// 因为Json::Value已经实现了各种数据类型的构造函数
Value(ValueType type = nullValue);
Value(Int value);
Value(UInt value);
Value(Int64 value);
Value(UInt64 value);
Value(double value);
Value(const char* value);
Value(const char* begin, const char* end);
Value(bool value);
Value(const Value& other);
Value(Value&& other);
  • 检测保存的数据类型
// 检测保存的数据类型
bool isNull() const;
bool isBool() const;
bool isInt() const;
bool isInt64() const;
bool isUInt() const;
bool isUInt64() const;
bool isIntegral() const;
bool isDouble() const;
bool isNumeric() const;
bool isString() const;
bool isArray() const;
bool isObject() const;
  • 基础数据类型访问并转换
const char* asCString() const;
JSONCPP_STRING asString() const;
Int asInt() const;
UInt asUInt() const;
Int64 asInt64() const;
UInt64 asUInt64() const;
LargestInt asLargestInt() const;
LargestUInt asLargestUInt() const;
float asFloat() const;
double asDouble() const;
bool asBool() const;
  • 对json数组的操作
ArrayIndex size() const;
Value& operator[](ArrayIndex index);
Value& operator[](int index);
const Value& operator[](ArrayIndex index) const;
const Value& operator[](int index) const;
// 根据下标的index返回这个位置的value值
// 如果没找到这个index对应的value, 返回第二个参数defaultValue
Value get(ArrayIndex index, const Value& defaultValue) const;
const_iterator begin() const;
const_iterator end() const;
iterator begin();
iterator end();
  • 对json对象的操作
// 联想stl中的map
obj["hello"] = "world";
obj["hello"];

Value& operator[](const char* key);
const Value& operator[](const char* key) const;
Value& operator[](const JSONCPP_STRING& key);
const Value& operator[](const JSONCPP_STRING& key) const;
Value& operator[](const StaticString& key);

// 通过key, 得到value值
Value get(const char* key, const Value& defaultValue) const;
Value get(const char* begin, const char* end, const Value& defaultValue) const;
Value get(const JSONCPP_STRING& key, const Value& defaultValue) const;
Value get(const CppTL::ConstString& key, const Value& defaultValue) const;

// 得到对象中所有的键值
typedef std::vector<std::string> Members;
Members getMemberNames() const;
  • 将Value对象数据序列化为string
// 序列化得到的字符串有样式 -> 带换行 -> 方便阅读
// 写配置文件的时候
std::string toStyledString() const;
  • // 序列化得到的字符串有样式 -> 带换行 -> 方便阅读
    // 写配置文件的时候
    std::string toStyledString() const;
    
  • 数组追加元素

 Value& append(const Value& value);

4: Reader 类

bool Json::Reader::parse(const std::string& document,
    Value& root, bool collectComments = true);
	参数:
		- document: json格式字符串
        - root: 传出参数, 存储了json字符串中解析出的数据
        - collectComments: 保存json字符串中的注释信息 // /**/

// 通过begindoc和enddoc指针定位一个json字符串
// 这个字符串可以是完成的json字符串, 也可以是部分json字符串
bool Json::Reader::parse(const char* beginDoc, const char* endDoc,
    Value& root, bool collectComments = true);
	
// write的文件流  -> ofstream    -> wo
// read的文件流   -> ifstream	 -> ri
// 假设要解析的json数据在磁盘文件中
// is流对象指向一个磁盘文件, 读操作
bool Json::Reader::parse(std::istream& is, Value& root, bool collectComments = true);

5: FastWriter 类

// 将数据序列化 -> 单行
// 进行数据的网络传输
std::string Json::FastWriter::write(const Value& root);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值