C++ json 解析器

http 请求时,经常需要读取 json,于是我自己写了一个轻量级的 O ( n 2 ) O(n^2) O(n2) json 解析。(只读,不修改)

原理很简单,递归建树即可。

性能一般般,不过一般的 http 请求很够用了

#include<bits/stdc++.h>
using namespace std;
struct Json {
	int type;
	/*
	1 数据
	2 []
	3 {}
	*/
	string dat;
	vector<string>name;
	vector<Json>child;
	void output(int dep=0) {
		for(int i=0; i<dep; i++) putchar(' ');
		if(type == 1) printf("%s\n",dat.c_str());
		else if(type == 2) {
			printf("[\n");
			for(int i=0; i<child.size(); i++) child[i].output(dep+2);
			for(int i=0; i<dep; i++) putchar(' ');
			printf("]\n");
		} else if(type == 3) {
			printf("{\n");
			for(int i=0; i<child.size(); i++) {
				for(int i=0; i<dep; i++) putchar(' ');
				// 如果键值对是字符串,就显示在一行,否则分多行显示
				if(child[i].type == 1) printf("  %s: %s\n",name[i].c_str(),child[i].dat.c_str());
				else printf("  %s: \n",name[i].c_str()), child[i].output(dep+2);
			}
			for(int i=0; i<dep; i++) putchar(' ');
			printf("}\n");
		}
	}
	Json & operator [] (string s) {
		if(type==3)
			for(int i=0; i<name.size(); i++)
				if(name[i] == s)
					return child[i];
	}
	inline Json & operator [] (int i) {
		if(type==2) return child[i];
	}
	inline int asint() {
		return stoi(dat);
	}
	inline int size() {
		return child.size();
	}
};
Json dfs(string s, int l, int r) { // O(n^2) 的构造,不过一般的 json 够用了
	Json retval;
	int type=1;
	bool in_str=0;
	if(s[l] == '[') type=2;
	else if(s[l] == '{') type=3;
	if(type == 1) {
		if(s[l]=='"' && s[r]=='"') ++l,--r; // 删除双引号
		retval.dat = s.substr(l, r-l+1);
		retval.type = 1;
	} else if(type == 2) {
		int last=l+1, cnt=0, empty=1;
		for(int i=l+1; i<r; i++) {
			if(s[i]!=' ') empty=0;
			if(s[i]=='"') in_str=!in_str;
			if(!in_str) {
				if(s[i]=='[' || s[i]=='{') cnt++;
				else if(s[i]==']' || s[i]=='}') cnt--;
				if(cnt==0 && s[i]==',') retval.child.push_back(dfs(s,last,i-1)), last=i+1;
			}
		}
		if(!empty) retval.child.push_back(dfs(s,last,r-1));
		retval.type = 2;
	} else if(type == 3) {
		int last=l+1, cnt=0, empty=1;
		for(int i=l+1; i<r; i++) {
			if(s[i]!=' ') empty=0;
			if(s[i]=='"') in_str=!in_str;
			if(!in_str) {
				if(s[i]==' ') continue;
				else if(s[i]=='[' || s[i]=='{') cnt++;
				else if(s[i]==']' || s[i]=='}') cnt--;
				if(cnt==0 && s[i]==':') {
					if(s[last]=='"' && s[i-1]=='"') retval.name.push_back(s.substr(last+1, i-last-2)); // 删除双引号
					else retval.name.push_back(s.substr(last, i-last));
					last=i+1;
				} else if(cnt==0 && s[i]==',') retval.child.push_back(dfs(s,last,i-1)), last=i+1;
			}
		}
		if(!empty) retval.child.push_back(dfs(s,last,r-1));
		retval.type = 3;
	}
	return retval;
}
Json Tojson(string s) {
	int in_str=0;
	string s2; // 去除多余空格
	for(int i=0; i<s.size(); i++) {
		if(s[i]=='"') in_str=!in_str;
		else if(in_str || (s[i]!=32 && s[i]!=9 && s[i]!=10 && s[i]!=13)) s2+=s[i];
	}
	return dfs(s2,0,s2.size()-1);
}
int main() {
	
	// 以字符串构造。必须保证json格式正确(空格没关系)
	Json test = Tojson("{a:114514, b:\"abc\"}");
	
	// 访问子节点
	Json child = test["a"];
	
	// 转换为 int
	cout << child.asint() << endl;
	
	// 直接获取 string 类型的数据
	cout << child.dat << endl;
	
	
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值