一个用C++写的Json解析与处理库

什么是Json?这个库能做什么?

JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write.

Json 是一种轻量的数据交换格式,和 XML 一样在 Web 开发中非常常用。在 Ajax 的应用中,前台基本上会用到 JSON 作为数据交换格式,因为在 JS 里面可以通过 JSON.parse() 函数对 JSON 格式的字符串进行解析得到 JS 对象,通过这个 JS 对象可以轻松地获取和修改里面的数据。而这个库 ggicci::Json 可以像 JS 一样通过解析获得一个类似的 C++ 对象。通过这个 C++ 对象,你可以像使用 JS 一样对数据进行获取和修改,语法上基本类似。只不过 C++ 是强类型语言,所以当你在试图用不一样的数据类型去获取里面的值的时候会抛异常。至于 C++ 是否需要 JSON 解析器,答案是肯定的,比如某个 CS 架构的程序,服务器端有某些页面采用 web 技术输出 JSON 数据,客户端是 C++ 客户端,它向这些页面发送 HTTP 请求并接收到 JSON 数据,这些数据就需要解析以配合客户端的使用。当然除非客户端只是输出这些字符串或者客户端采用与 C++ 与 JS 混合编程方式,让 JS 去处理这些数据。

更好的阅读体验请传送门传送到我的个人博客对应地址:http://ggicci.me/wordpress/cpp/一个用c写的json解析与处理库/

项目地址和文档

Github:https://github.com/ggicci/ggicci--json

GGICCI:http://ggicci.me/works/json

文档:http://ggicci.me/works/json/doc

看一个简单例子

#include <iostream>
#include "gci-json.h"

using namespace std;
using namespace ggicci;

int main(int argc, char const *argv[])
{
    // Parse a string to get a Json object
	Json json = Json::Parse("{			\
		\"id\": 18293, 					\
		\"name\": \"Ggicci\", 			\
		\"birthday\": [1991, 11, 10], 	\
		\"man\": true 					\
	}");

	cout << "json = " << json << endl;
	cout << "-----------------------" << endl;
	cout << "id: " << json["id"] << endl;
	cout << "name: " << json["name"] << endl;
	cout << "birthday-year: " << json["birthday"][0] << endl;
	cout << "birthday-month: " << json["birthday"][1] << endl;
	cout << "birthday-day: " << json["birthday"][2] << endl;
	cout << "man: " << boolalpha << json["man"] << endl;
	cout << "-----------------------" << endl;

	json["name"] = "Mingjie Tang";
	// add property: method 1
	json["school"] = "Northwest A&F University";
	// add property: method 2
	json.AddProperty("traits", Json::Parse("[]").Push("sympathetic").Push("independent"));
	cout << "json = " << json << endl;
	cout << "-----------------------" << endl;

	json["birthday"].Remove(0);
	json.Remove("id").Remove("school");
	cout << "json = " << json << endl;

	return 0;
}

/*
output:
-----------------------
id: 18293
name: "Ggicci"
birthday-year: 1991
birthday-month: 11
birthday-day: 10
man: true
-----------------------
json = { "birthday": [ 1991, 11, 10 ], "id": 18293, "man": true, "name": "Mingjie Tang", "school": "Northwest A&F University", "traits": [ "sympathetic", "independent" ] }
-----------------------
json = { "birthday": [ 11, 10 ], "man": true, "name": "Mingjie Tang", "traits": [ "sympathetic", "independent" ] }
*/

如果你对 JSON 的处理比较熟悉(你可能会使用 JS 处理 JSON 数据),你会发现上面的代码很好理解。

与 JS 的使用比较(语法层面上)

对于原始的 JSON 字符串 str: { "id": 1000, "name": "ggicci", "birthday": [1991, 11, 10] }

JS: var str = '{ "id": 1000, "name": "ggicci", "birthday": [1991, 11, 10] }';

C++: const char* str = "{\"id\": 1000, \"name\": \"ggicci\", \"birthday\": [1991, 11, 10] }";

ggicci::Json 和 JS 中 JSON 的使用比较
功能JS 的 JSON 解析器ggicci::Json(下面假设已声明使用命名空间 ggicci)
解析并得到JSON对象var json = JSON.parse(str);Json json = Json::Parse(str);
获取Numbervar id = json["id"];int id = json["id"];
获取Stringvar name = json["name"];const char* name = json["name"];
string name = json["name"];
获取Arrayvar birthday = json["birthday"];Json birthday = json["birthday"]; // 拷贝
Json &birthday = json["birthday"]; // 引用
Json *birthday = json["birthday"]; // 指针
ggicci::Json 中获取 null(需要通过 Json 对象,IsNull() 函数用来确定接收到的数据是否是 null) 获取Object(需要通过 Json 对象) 获取true,false(通过 bool 值就可以了)
修改Numberjson["id"] = 19214;json["id"] = 19214;
修改Stringjson["name"] = "Mingjie Tang";json["name"] = "Mingjie Tang";
修改Arrayjson["birthday"][2] = 11;json["birthday"][2] = 11;
添加数据(Array)json["birthday"].push(2013);
json["birthday"].push("hello");
json["birthday"].Push(2013).Push("hello");
添加数据(Object)json["man"] = true;json["man"] = true;
json.AddProperty("man", true);
删除数据(Array)use pop, unshift ...json["birthday"].Remove(0); // 不能级联
删除数据(Object)delete json["name"];json.Remove("name").Remove("id"); // 可以级联
获取Object的所有Keys// 复杂vector<string> keys = json.Keys();

异常处理

解析异常

int main(int argc, char const *argv[])
{
	try
	{
		Json json = Json::Parse("[1, 2, 2, { \"id\": 183, \"name\": 'Ggicci' } ]");
	}
	catch (exception& e)
	{
		cout << e.what() << endl; // SyntaxError: Unexpected token ' at pos 31
	}
	return 0;
}

在 Chrome 下利用 JS 的 JSON::parse() 函数解析抛出的异常:


数据获取异常

int main(int argc, char const *argv[])
{
    try
	{
		Json json = Json::Parse("[1, 2, 3, 4]");
		int first = json[0]; // no problem
		const char* second = json[1]; // cause exception
	}
	catch (exception& e)
	{
		cout << e.what() << endl; // OperationError: Illegal extract opeartion from Number to String
	}
	return 0;
}

非法操作异常

int main(int argc, char const *argv[])
{
    try
	{
		Json json = Json::Parse("[1, 2, 3, 4]");
		json.AddProperty("name", "Ggicci"); // cause exception
	}
	catch (exception& e)
	{
		cout << e.what() << endl; // OperationError: Illegal add property opeartion on Array
	}
	return 0;
}

类型检测

int main(int argc, char const *argv[])
{
    Json json = Json::Parse("[1, \"hello\", { \"title\": null }, false ]");
	json.IsArray(); 	// true
	json[0].IsNumber();	// true
	json[1].IsString();	// true
	json[2].IsObject(); // true
	json[2]["title"].IsNull();	//true
	json[3].IsBool();	// true

	if (json.IsArray())
	{
		for (int i = 0; i < json.Size(); ++i)
		{
			switch (json[i].DataKind())
			{
				case Json::kNumber: cout << "number: "; break;
				case Json::kString: cout << "string: "; break;
				case Json::kArray:  cout << "array:  "; break;
				case Json::kObject: cout << "object: "; break;
				case Json::kBool:   cout << "bool:   "; break;
				case Json::kNull:   cout << "null:   "; break;
				default: break;
			}
			cout << json[i] << endl;
		}
	}
	return 0;
}

/*
output:
number: 1
string: "hello"
object: { "title": null }
bool:   false
*/

写在最后

如果可以,请你使用smiley

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值