简易的 C++ JSON解析器

Github地址:X-Thinker/JSON-Parser: 简易的JSON解析器/A Tiny JSON Parser (github.com)icon-default.png?t=N7T8https://github.com/X-Thinker/JSON-Parser

README:

CppJSON.h

#ifndef CppJSON_h
#define CppJSON_h

#include <iostream>
#include <sstream>
#include <typeinfo>
#include <fstream>
#include <memory>

namespace JSON
{
	/*----------JSON类型----------*/
	//抽象基类CppJSON,不可实例化
	class CppJSON
	{
	public:
		//类内枚举,定义JSON数据类型
		enum CppJSON_Type { JSON_Initial, JSON_Error, JSON_NULL, JSON_Bool, JSON_Number, JSON_String, JSON_Array, JSON_Object };

		//构造函数与析构函数,构造函数使用初始化列表,析构函数是虚函数
		CppJSON(CppJSON_Type ini = JSON_Initial, CppJSON* left = nullptr, CppJSON* right = nullptr,
			const std::string& key_name = "name") :type(ini), prev(left), next(right), child(nullptr), key("name") {}
		virtual ~CppJSON() = 0;

		//修改JSON数据结构内部成员变量
		void set_prev(CppJSON* left) { prev = left; }
		void set_next(CppJSON* right) { next = right; }
		void set_key(const std::string& name) { key = name; }
		void set_child(CppJSON* first) { child = first; }

		//返回JSON数据结构内部成员变量
		CppJSON* return_prev() const { return prev; }
		CppJSON* return_next() const { return next; }
		const std::string return_key() const { return key; }
		CppJSON* return_child() const { return child; }
		CppJSON_Type return_type()const { return type; }

		//纯虚函数,后续array和object需要覆写
		virtual CppJSON& operator [] (int pos) const;
		virtual CppJSON& operator [] (const std::string key_name) const;
		virtual void push_back(CppJSON* item);
		virtual void insert(CppJSON* item, int pos);
		virtual void split(int pos);
		virtual void split(const std::string& key_name);

	private:
		CppJSON_Type type;
		//同一结构中的前一个元素与后一个元素
		CppJSON* prev, * next, * child;
		std::string key;

		//禁用拷贝构造函数与赋值运算符重载(设为private并不予实现)
		CppJSON(const CppJSON& rhs) {}
		CppJSON& operator = (const CppJSON& rhs) {}
	};
	//错误类型用以处理异常情况
	class CppJSON_Error :public CppJSON
	{
	public:
		enum Error_Type { No_Error, Invalid_Type, Out_Range, Invalid_Key, Invalid_Json_Text, Bad_Allocate, Open_File_Fail, Unknown_Error };
		CppJSON_Error() :CppJSON(JSON_Error), error_type(No_Error), exception() {}
		~CppJSON_Error() {}
		CppJSON& operator [] (int pos);
		CppJSON& operator [] (std::string key_name);
		void throw_exception(Error_Type type);
	private:
		Error_Type error_type;
		std::string exception;
	};
	//值为null的数据类型
	class CppJSON_NULL :public CppJSON
	{
	public:
		CppJSON_NULL() :CppJSON(JSON_NULL) {}
		~CppJSON_NULL() {}
	};
	//值为false或true的数据类型
	class CppJSON_Bool :public CppJSON
	{
	public:
		CppJSON_Bool() :CppJSON(JSON_Bool), valuebool(false) {}
		~CppJSON_Bool() {}
		void set_valuebool(bool vb) { valuebool = vb; }
		bool return_valuebool() const { return valuebool; }
	private:
		bool valuebool;
	};
	//值为数值的数据类型
	class CppJSON_Number :public CppJSON
	{
	public:
		CppJSON_Number() :CppJSON(JSON_Number), valueint(0), valuedouble(0.0), numbertype(false) {}
		~CppJSON_Number() {}

		//修改/查询数值型JSON的数值
		void set_valueint(int vi) { valueint = vi; }
		int return_valueint() const { return valueint; }
		void set_valuedouble(double vd) { valuedouble = vd; }
		double return_valuedouble() const { return valuedouble; }
		void set_numbertype(bool nt) { numbertype = nt; }
		bool return_numbertype() const { return numbertype; }

	private:
		int valueint;
		double valuedouble;
		bool numbertype;//数值类型默认为false即int型,若为true则为double型
	};
	//值为字符串的数据类型
	class CppJSON_String :public CppJSON
	{
	public:

		CppJSON_String() :CppJSON(JSON_String) {}
		~CppJSON_String() {}

		void set_valuestring(const std::string& vs) { valuestring = vs; }
		std::string return_valuestring() const { return valuestring; }

	private:
		std::string valuestring;
	};
	//值为数组的数据类型
	class CppJSON_Array :public CppJSON
	{
	public:
		CppJSON_Array() :CppJSON(JSON_Array) {}
		~CppJSON_Array() {}

		//重载 [] 运算符,使数组类型可以通过下标直接访问其内部元素
		CppJSON& operator [] (int pos) const override;

		void push_back(CppJSON* item) override;
		void insert(CppJSON* item, int pos) override;
		void split(int pos) override;
	};
	//值为对象的数据类型
	class CppJSON_Object :public CppJSON
	{
	public:
		CppJSON_Object() :CppJSON(JSON_Object) {}
		~CppJSON_Object() {}

		//重载 [] 运算符使对象类型可以通过key直接访问其内部元素
		CppJSON& operator [] (const std::string key_name) const override;

		void push_back(CppJSON* item) override;
		void split(const std::string& key_name) override;
	};
	/*----------JSON类型----------*/



	/*----------对外接口----------*/
	//解析函数
	enum parser_mode { file, text };
	std::shared_ptr<CppJSON> parser(std::string str, parser_mode mode);
	std::shared_ptr<CppJSON> parser(char* str, parser_mode mode);
	//压缩json文本(删除空格、空行、注释)
	std::string minify(std::stringstream& message);
	std::string minify(std::string& msg);
	//重载 << 运算符方便输出
	std::ostream& operator << (std::ostream& os, CppJSON* JSON_Print);
	/*----------对外接口----------*/
}

#endif

CppJSON.cpp

#include "CppJSON.h"

namespace JSON
{
	//全局异常
	CppJSON_Error* error = new CppJSON_Error;

	/*----------类成员函数模块----------*/
	CppJSON::~CppJSON() {}
	CppJSON& CppJSON::operator [] (int pos) const { error->throw_exception(CppJSON_Error::Invalid_Type); return *error; }
	CppJSON& CppJSON::operator [] (const std::string key_name) const { error->throw_exception(CppJSON_Error::Invalid_Type); return *error; }
	void CppJSON::push_back(CppJSON* item) { error->throw_exception(CppJSON_Error::Invalid_Type); }
	void CppJSON::insert(CppJSON* item, int pos) { error->throw_exception(CppJSON_Error::Invalid_Type); }
	void CppJSON::split(int pos) { error->throw_exception(CppJSON_Error::Invalid_Type); }
	void CppJSON::split(const std::string& key_name) { error->throw_exception(CppJSON_Error::Invalid_Type); }


	//数组通过下标访问内部元素
	CppJSON& CppJSON_Array::operator [] (int pos) const
	{
		CppJSON* location = this->return_child();
		while (location != nullptr && pos > 0)
			location = location->return_next(), --pos;
		//越界异常,返回错误类型
		if (pos != 0 || location == nullptr)
		{
			error->throw_exception(CppJSON_Error::Out_Range);
			return *error;
		}
		return *location;
	}
	//对象通过关键字访问内部元素
	CppJSON& CppJSON_Object::operator [] (const std::string key_name) const
	{
		CppJSON* location = this->return_child();
		while (location != nullptr && key_name != location->return_key())
			location = location->return_next();
		//找不到关键字,返回错误类型
		if (location == nullptr)
		{
			error->throw_exception(CppJSON_Error::Invalid_Key);
			return *error;
		}
		return *location;
	}

	//在数组尾部加入新元素
	void CppJSON_Array::push_back(CppJSON* item)
	{
		CppJSON* preloc = this->return_child(), * loc = this->return_child();
		//空数组
		if (loc == nullptr) { this->set_child(item); return; }
		//非空数组
		while (loc != nullptr)
			preloc = loc, loc = loc->return_next();
		preloc->set_next(item);
		item->set_prev(preloc);
		return;
	}
	//在对象尾部加入新元素
	void CppJSON_Object::push_back(CppJSON* item)
	{
		CppJSON* preloc = this->return_child(), * loc = this->return_child();
		//空对象
		if (loc == nullptr) { this->set_child(item); return; }
		//非空对象
		while (loc != nullptr)
			preloc = loc, loc = loc->return_next();
		preloc->set_next(item);
		item->set_prev(preloc);
		return;
	}

	//在数组指定位置插入新元素
	void CppJSON_Array::insert(CppJSON* item, int pos)
	{
		//在头部插入
		if (pos == 0)
		{
			item->set_next(this->return_child());
			if (this->return_child() != nullptr)
				this->return_child()->set_prev(item);
			this->set_child(item);
			return;
		}
		CppJSON* prev_loc = &(*this)[pos - 1];
		//如果上述过程抛出异常直接退出
		if (typeid(*error) == typeid(*prev_loc))
			return;
		//如果pos-1的位置为队尾则退化成push_back
		if (prev_loc->return_next() != nullptr)
		{
			CppJSON* next_loc = prev_loc->return_next();
			prev_loc->set_next(item), item->set_prev(prev_loc);
			item->set_next(next_loc), next_loc->set_prev(item);
		}
		else
			prev_loc->set_next(item), item->set_prev(prev_loc);
		return;
	}

	//删除指定数组元素
	void CppJSON_Array::split(int pos)
	{
		CppJSON* detath_item = &(*this)[pos];
		if (typeid(*error) == typeid(*detath_item))
			return;
		//删除首元素
		if (pos == 0)
		{
			this->set_child(detath_item->return_next());
			if (detath_item->return_next() != nullptr)
				detath_item->return_next()->set_prev(nullptr);
			detath_item->set_next(nullptr);
			delete detath_item;
			return;
		}
		//非首元素
		detath_item->return_prev()->set_next(detath_item->return_next());
		if (detath_item->return_next() != nullptr)
			detath_item->return_next()->set_prev(detath_item->return_prev());
		detath_item->set_next(nullptr), detath_item->set_prev(nullptr);
		delete detath_item;
		return;
	}
	//删除指定对象元素
	void CppJSON_Object::split(const std::string& key_name)
	{
		CppJSON* detath_item = &(*this)[key_name];
		if (typeid(*error) == typeid(*detath_item))
			return;
		//删除首元素
		if (this->return_child() == detath_item)
		{
			this->set_child(detath_item->return_next());
			if (detath_item->return_next() != nullptr)
				detath_item->return_next()->set_prev(nullptr);
			detath_item->set_next(nullptr);
			delete detath_item;
			return;
		}
		//非首元素
		detath_item->return_prev()->set_next(detath_item->return_next());
		if (detath_item->return_next() != nullptr)
			detath_item->return_next()->set_prev(detath_item->return_prev());
		detath_item->set_next(nullptr), detath_item->set_prev(nullptr);
		delete detath_item;
		return;
	}
	/*----------类成员函数模块----------*/



	/*----------异常模块----------*/
	//对不同错误类型抛出不同异常
	void CppJSON_Error::throw_exception(Error_Type type)
	{
		switch (type)
		{
		case Invalid_Type: exception = "This procedure triggers an error \"Invalid type\""; break;
		case Out_Range: exception = "This procedure triggers an error \"Subscript out of range\""; break;
		case Invalid_Key: exception = "This procedure triggers an error \"Invalid key\""; break;
		case Invalid_Json_Text: exception = "This procedure triggers an error \"Invalid json texts\""; break;
		case Bad_Allocate: exception = "This procedure triggers an error \"Bad allocated\""; break;
		case Open_File_Fail: exception = "This procedure triggers an error \"Fail to open the file\""; break;
		default: exception = "This procedure triggers an unknown error"; break;
		}
		error_type = type;
		std::cout << exception << std::endl;
		return;
	}
	//错误类型的[]运算符重载,处理后续数组和对象在进行连续的[]访问中抛出的异常
	CppJSON& CppJSON_Error::operator [] (int pos) { throw_exception(Invalid_Type); return *error; }
	CppJSON& CppJSON_Error::operator [] (std::string key_name) { throw_exception(Invalid_Type); return *error; }
	//内存分配失败抛出异常
	CppJSON* bad_allocated() { error->throw_exception(CppJSON_Error::Bad_Allocate); return error; }
	//无效的Json文本抛出异常
	CppJSON* invalid_json_text(std::stringstream& message) 
	{
		error->throw_exception(CppJSON_Error::Invalid_Json_Text); 
		std::string fail_pos;
		getline(message, fail_pos);
		fail_pos += "(...omit...)";
		//把解析失败的行内容输出,方便用户检查json文本错误
		std::cout << "Parsing failed: " << fail_pos << std::endl;
		return error;
	}
	/*----------异常模块----------*/



	/*---------功能函数模块---------*/
	//删除整个json结构
	void delete_json(CppJSON* detach_json)
	{
		CppJSON* next = detach_json;
		while (detach_json)
		{
			next = detach_json->return_next();
			if (detach_json->return_child() != nullptr)
				delete_json(detach_json->return_child());
			delete detach_json;
			detach_json = next;
		}
		return;
	}
	//压缩json文本,去除空白格与格式
	std::string minify(std::stringstream& message) 
	{
		std::string msg = message.str(); 
		return minify(msg);
	}
	std::string minify(std::string& msg)
	{
		int point_write = 0, point_read = 0;
		while (msg[point_read] != '\0')
		{
			switch (msg[point_read])
			{
			case ' ': ++point_read; break;
			case '\n': ++point_read; break;
			case '\r': ++point_read; break;
			case '\t': ++point_read; break;//跳过空白格
			case '\"':
				msg[point_write++] = msg[point_read++];
				while (msg[point_read] != '\0' && msg[point_read] != '\"')
					msg[point_write++] = msg[point_read++];
				msg[point_write++] = msg[point_read++];
				break;
			default: msg[point_write++] = msg[point_read++]; break;
			}
		}
		msg[point_write] = '\0';
		std::string res(msg, 0, ++point_write);
		std::cout << res << std::endl;
		return res;
	}
	//跳过空白格
	std::stringstream& skip_whitespace(std::stringstream& message) { while (message.peek() > 0 && message.peek() <= 32) message.ignore(); return message; }
	//获取一个元素的key值
	bool get_keyname(std::string& kn, std::stringstream& message)
	{
		if (message.peek() != '\"')
			return false;
		message.ignore();
		kn.clear();
		getline(message, kn, '\"');
		if (kn.size())
			return true;
		else
			return false;
	}
	/*---------功能函数模块---------*/



	/*----------解析模块----------*/
	//前置声明
	CppJSON* parse_object(std::stringstream& message);
	//以string参数进行解析
	std::shared_ptr<CppJSON> parser(std::string path, parser_mode mode)
	{
		std::stringstream json_text;
		if (mode == file)
		{
			std::ifstream fin(path);
			//文件打开失败抛出异常
			if (!fin.is_open())
			{
				error->throw_exception(CppJSON_Error::Open_File_Fail);
				return std::shared_ptr<CppJSON>(error);
			}
			//将fin流中内容输入到json_text
			json_text << fin.rdbuf();
			fin.close();
		}
		else if (mode == text)
			json_text << path;
		else//如果解析模式错误则会抛出未知错误
		{
			error->throw_exception(CppJSON_Error::Unknown_Error);
			return std::shared_ptr<CppJSON>(error);
		}
		CppJSON* res = parse_object(skip_whitespace(json_text));
		//在json文本后有除终止符外的其他非空白字符
		if (skip_whitespace(json_text).peek() != -1)
		{
			invalid_json_text(json_text);
			return std::shared_ptr<CppJSON>(error);
		}
		if (typeid(*res) == typeid(*error)) 
			return std::shared_ptr<CppJSON>(error);
		std::shared_ptr<CppJSON> ptr(res, delete_json);
		std::cout << ptr.get() << std::endl;
		return ptr;
	}
	//以char*参数进行解析,兼容C
	std::shared_ptr<CppJSON> parser(char* path, parser_mode mode)
	{
		//把char*的内容导入string后用parser的string重载完成解析
		std::string ps(path);
		return parser(ps, mode);
	}

	//解析函数
	//前置声明
	CppJSON* parse_null(std::stringstream& message);
	CppJSON* parse_bool(std::stringstream& message);
	CppJSON* parse_string(std::stringstream& message);
	CppJSON* parse_number(std::stringstream& message);
	CppJSON* parse_array(std::stringstream& message);
	CppJSON* parse_object(std::stringstream& message);

	CppJSON* parse_value(std::stringstream& message)
	{
		char ch_mes = message.peek();
		if (ch_mes == 'n')
			return parse_null(message);
		else if (ch_mes == 'f' || ch_mes == 't')
			return parse_bool(message);
		else if (ch_mes == '\"')
			return parse_string(message);
		else if (ch_mes == '-' || ch_mes == '+' || isdigit(ch_mes))
			return parse_number(message);
		else if (ch_mes == '[')
			return parse_array(message);
		else if (ch_mes == '{')
			return parse_object(message);
		else//如果出现错误情况,抛出无效Json文本异常
			return invalid_json_text(message);
	}
	CppJSON* parse_null(std::stringstream& message)
	{
		//检查是否为有效的null值
		if (message.peek() != 'n')
			return invalid_json_text(message);
		CppJSON_NULL* item_null = new CppJSON_NULL;
		//分配失败抛出异常
		if (item_null == nullptr)
			return bad_allocated();
		message.ignore(4);//null四个字符
		return item_null;
	}
	CppJSON* parse_bool(std::stringstream& message)
	{
		char ch = message.peek();
		if (ch != 'f' && ch != 't')
			return invalid_json_text(message);
		CppJSON_Bool* item_bool = new CppJSON_Bool;
		if (item_bool == nullptr)
			return bad_allocated();
		//设置bool的类型
		if (ch == 'f') item_bool->set_valuebool(false), message.ignore(5);
		else item_bool->set_valuebool(true), message.ignore(4);
		return item_bool;
	}
	CppJSON* parse_string(std::stringstream& message)
	{
		if (message.peek() != '\"')
			return invalid_json_text(message);
		CppJSON_String* item_string = new CppJSON_String;
		if (item_string == nullptr)
			return bad_allocated();
		std::string vs;
		message.ignore();
		//以"为分割符,将string值抽出
		getline(message, vs, '\"');
		item_string->set_valuestring(vs);
		return item_string;
	}
	CppJSON* parse_number(std::stringstream& message)
	{
		char ch_mes = message.peek();
		if (ch_mes != '-' && ch_mes != '+' && !isdigit(ch_mes))
			return invalid_json_text(message);
		std::string num_string;
		bool num_type = false;
		//值为number的所有可能出现的字符
		while (ch_mes == '-' || ch_mes == '+' || ch_mes == 'e' || ch_mes == 'E' || ch_mes == '.' || isdigit(ch_mes))
			num_string.push_back(message.get()), ch_mes = message.peek(), num_type = (ch_mes == '.' || ch_mes == 'e' || ch_mes == 'E') ? true : false;
		CppJSON_Number* item_number = new CppJSON_Number;
		if (item_number == nullptr)
			return bad_allocated();
		//根据数字中是否出现小数点或者科学计数法来判断数值为double或int
		item_number->set_numbertype(num_type);
		if (num_type)
			item_number->set_valuedouble(std::stod(num_string));
		else
			item_number->set_valueint(std::stoi(num_string));
		return item_number;
	}
	CppJSON* parse_array(std::stringstream& message)
	{
		if (message.peek() != '[')
			return invalid_json_text(message);
		message.ignore();
		CppJSON_Array* item_array = new CppJSON_Array;
		if (item_array == nullptr)
			return bad_allocated();
		CppJSON* item_child = parse_value(skip_whitespace(message));
		//解析失败抛出异常
		if (typeid(*item_child) == typeid(*error))
			return error;
		//连接子结点
		item_array->set_child(item_child);

		CppJSON* item_otherchild = nullptr;
		while (skip_whitespace(message).peek() == ',')
		{
			message.ignore();
			item_otherchild = parse_value(skip_whitespace(message));
			if (typeid(*item_otherchild) == typeid(*error))
				return error;
			//连接各子结点
			item_child->set_next(item_otherchild), item_otherchild->set_prev(item_child);
			item_child = item_otherchild;
		}

		if (message.peek() != ']')
			return invalid_json_text(message);
		message.ignore();
		return item_array;
	}
	CppJSON* parse_object(std::stringstream& message)
	{
		if (message.peek() != '{')
			return invalid_json_text(message);
		message.ignore();
		CppJSON* item_object = new CppJSON_Object;
		if (item_object == nullptr)
			return bad_allocated();
		//对象中为key-value键值对,所以首先应该出现key或者 }(空的对象)
		if (skip_whitespace(message).peek() == '}')
			return item_object;
		if (message.peek() != '\"')
			return invalid_json_text(message);

		//message.ignore();
		std::string item_keyname;
		//key值解析失败
		if (!get_keyname(item_keyname, message))
			return invalid_json_text(message);
		if (skip_whitespace(message).peek() != ':')
			return invalid_json_text(message);

		message.ignore();
		CppJSON* item_child = parse_value(skip_whitespace(message));
		if (typeid(*item_child) == typeid(*error))
			return error;
		item_child->set_key(item_keyname);
		item_object->set_child(item_child);

		CppJSON* item_otherchild = nullptr;
		while (skip_whitespace(message).peek() == ',')
		{
			message.ignore(), skip_whitespace(message);
			if (!get_keyname(item_keyname, message))
				return invalid_json_text(message);
			if (skip_whitespace(message).peek() != ':')
				return invalid_json_text(message);
			message.ignore();
			item_otherchild = parse_value(skip_whitespace(message));
			if (typeid(*item_otherchild) == typeid(*error))
				return error;
			item_otherchild->set_key(item_keyname);
			item_child->set_next(item_otherchild), item_otherchild->set_prev(item_child);
			item_child = item_otherchild;
		}

		if (message.peek() != '}')
			return invalid_json_text(message);
		message.ignore();
		return item_object;
	}
	/*----------解析模块----------*/



	/*----------输出模块----------*/
	//静态全局变量deep用来反映输出时的递归深度以格式化输出
	static int print_deep = 0;
	//输出函数
	std::ostream& print_bool(std::ostream& os, CppJSON_Bool* pb) { pb->return_valuebool() ? os << "true" : os << "false"; return os; }
	std::ostream& print_null(std::ostream& os, CppJSON_NULL* pn) { os << "null"; return os; }
	std::ostream& print_string(std::ostream& os, CppJSON_String* ps) { os << '\"' << ps->return_valuestring() << '\"'; return os; }
	std::ostream& print_number(std::ostream& os, CppJSON_Number* pn) { pn->return_numbertype() ? os << pn->return_valuedouble() : os << pn->return_valueint(); return os; }
	std::ostream& print_array(std::ostream& os, CppJSON_Array* pa)
	{
		os << '[';
		CppJSON* pa_child = pa->return_child();
		while (pa_child != nullptr)
		{
			os << pa_child;
			pa_child = pa_child->return_next();
			if (pa_child != nullptr)
				os << ", ";
		}
		os << ']';
		return os;
	}
	std::ostream& print_object(std::ostream& os, CppJSON_Object* po)
	{
		++print_deep, os << '{';
		CppJSON* po_child = po->return_child();
		if (po_child != nullptr) os << '\n';
		while (po_child != nullptr)
		{
			for (int i = 1; i <= print_deep; i++)
				os << '\t';
			os << '\"' << po_child->return_key() << "\":\t";
			os << po_child;
			po_child = po_child->return_next();
			if (po_child != nullptr)
				os << ',';
			os << '\n';
		}
		for (int i = 1; i <= print_deep - 1; i++) os << '\t';
		--print_deep, os << '}';
		return os;
	}
	std::ostream& operator << (std::ostream& os, CppJSON* JSON_Print)
	{
		switch (JSON_Print->return_type())
		{
		case CppJSON::JSON_Bool: return print_bool(os, dynamic_cast<CppJSON_Bool*>(JSON_Print)); break;
		case CppJSON::JSON_NULL:return print_null(os, dynamic_cast<CppJSON_NULL*>(JSON_Print)); break;
		case CppJSON::JSON_String: return print_string(os, dynamic_cast<CppJSON_String*>(JSON_Print)); break;
		case CppJSON::JSON_Number: return print_number(os, dynamic_cast<CppJSON_Number*>(JSON_Print)); break;
		case CppJSON::JSON_Array: return print_array(os, dynamic_cast<CppJSON_Array*>(JSON_Print)); break;
		case CppJSON::JSON_Object: return print_object(os, dynamic_cast<CppJSON_Object*>(JSON_Print)); break;
		default: error->throw_exception(CppJSON_Error::Invalid_Type); return os; break;
		}
	}
	/*----------输出模块----------*/
}

 

JSON++ Build Status Introduction JSON++ is a light-weight JSON parser, writer and reader written in C++. JSON++ can also convert JSON documents into lossless XML documents. Contributors http://github.com/hjiang http://github.com/elanthis http://github.com/r-lyeh If you've made substantial contribution, please add your link here. Why another JSON parser? Perhaps because web service clients are usually written in dynamic languages these days, none of the existing C++ JSON parsers fitted my needs very well, so I wrote one that I used in another project. My goals for JSON++ were: Efficient in both memory and speed. No third party dependencies. JSON++ only depends on the standard C++ library. Cross platform. Robust. Small and convenient API. Most of the time, you only need to call one function and two function templates. Easy to integrate. JSON++ only has one source file and one header file. Just compile the source file and link with your program. Able to construct documents dynamically. JSON writer: write documents in JSON format. Other contributors have sinced added more functionalities: XML writer: convert documents to JSONx format. See http://goo.gl/I3cxs for details. XML writer: convert documents to JXML format. See https://github.com/r-lyeh/JXML for details. XML writer: convert documents to JXMLex format. See https://github.com/r-lyeh/JXMLex for details. XML writer: convert documents to tagged XML format. See https://github.com/hjiang/jsonxx/issues/12 for details. Compiler version You need a modern C++ compiler. For older compilers, please try legacy branch. Configuration Strict/permissive parsing JSONxx can parse JSON documents both in strict or permissive mode. When jsonxx::Settings::Parser is set to Strict, JSONxx parser will accept: Fully conformant JSON documents only. When jsonxx::Settings::Parser is set to Permissive, JSONxx parser will accept: Fully conformant JSON documents Ending commas in arrays and objects: { "array": [0,1,2,], } Single quoted strings: ['hello', "world"] C++ style comments: { "width": 320, "height": 240 } //Picture details Default value is Permissive. When jsonxx::Settings::UnquotedKeys is set to Enabled, JSONxx parser will accept: Unquoted keys: {name: "world"} Default value is Disabled. Assertions JSONxx uses internally JSONXX_ASSERT(...) macro that works both in debug and release mode. Set jsonxx::Settings::Assertions value to Disabled to disable assertions. Default value is Enabled. Usage The following snippets are from one of the unit tests. They are quite self-descriptive. using namespace std; using namespace jsonxx; string teststr( "{" " \"foo\" : 1," " \"bar\" : false," " \"person\" : {\"name\" : \"GWB\", \"age\" : 60,}," " \"data\": [\"abcd\", 42]," "}" ); // Parse string or stream Object o; assert(o.parse(teststr)); // Validation. Checking for JSON types and values as well assert(1 == o.get<Number>("foo")); assert(o.has<Boolean>("bar")); assert(o.has<Object>("person")); assert(o.get<Object>("person").has<Number>("age")); assert(!o.get<Object>("person").has<Boolean>("old")); assert(o.get<Object>("person").get<Boolean>("old", false)); assert(o.has<Array>("data")); assert(o.get<Array>("data").get<Number>(1) == 42); assert(o.get<Array>("data").get<String>(0) == "abcd"); assert(o.get<Array>("data").get<String>(2, "hello") == "hello"); assert(!o.has<Number>("data")); cout << o.json() << endl; // JSON output cout << o.xml(JSONx) << endl; // JSON to XML conversion (JSONx subtype) cout << o.xml(JXML) << endl; // JSON to XML conversion (JXML subtype) cout << o.xml(JXMLex) << endl; // JSON to XML conversion (JXMLex subtype) // Generate JSON document dynamically using namespace std; using namespace jsonxx; Array a; a << 123; a << "hello world"; a << 3.1415; a << 99.95f; a << 'h'; a << Object("key", "value"); Object o; o << "key1" << "value"; o << "key2" << 123; o << "key3" << a; cout << o.json() << endl; To do Custom JSON comments (C style /**/) when permissive parsing is enabled.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值