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;
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
C语言中有多种方法可以进行JSON解析。一种常用的方法是使用开源库RapidJSON。RapidJSON是一个只有头文件的C库,使用起来非常方便。你只需要下载并解压后,将include/rapidjson目录拷贝到你的项目中即可开始使用。RapidJSON支持SAX和DOM两种解析方式,SAX解析器JSON流解析为事件序列,而DOM解析器JSON解析为内存中的树形结构。 另外还有一个流行的C库是JsonCpp,也是用于JSON解析和生成的开源库。JsonCpp与RapidJSON具有很多相似的功能,但也有一些不同之处。你可以根据自己的需求选择使用其中的一个库来进行C语言中的JSON解析。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [json.zip_JSON_c/c++ json_c/c++ json 解析_json解析 c++_解析json](https://download.csdn.net/download/weixin_42662605/86531966)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [【C/C++C++Json解析和生成的开源库:RapidJsonJsonCpp](https://blog.csdn.net/weixin_43729127/article/details/129473932)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值