C++如何自己动手解析json

水森1016 2018-04-20 08:43:41
怎么用C++写一个简易的Json解析工具?求指导,求思路?修改
简单一点的方法,想两天搞定的
...全文
1623 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
Steps-of-time 2018-04-29
  • 打赏
  • 举报
回复
可以网上下载一个acl库,里面有相应的解析方法,都是一些很成熟的东西,之后自己可以封装相应的方法,从而达到自己的需求。具体的编译方式,库中有相应介绍方法。
小小蔷薇 2018-04-28
  • 打赏
  • 举报
回复
自己写麻烦,用jsoncpp比较方便
www_adintr_com 2018-04-28
  • 打赏
  • 举报
回复
在已经有词法分析器的基础上, 要解析 json 其实是非常简单的, 代码不超过 200 行, 下面这个就是我手动写的:

JsonItem* ParseJSArray(CLex& lex);
JsonItem* ParseJSObject(CLex& lex);

static JsonItem* ParseJSItem(CLex& lex)
{
	CToken tk = lex.get_token_no_lfeed();
	if (tk.is_number())
	{
		return new JsonItemInt((int)tk.get_number());
	}
	else if (tk.is_float())
	{
		return new JsonItemDouble(tk.get_double());
	}
	else if (tk.is_string())
	{
		return new JsonItemString(tk.get_string());
	}
	else if (tk.is_operator(CTokenType::OpBracketLeft))
	{
		return ParseJSArray(lex);
	}
	else if (tk.is_operator(CTokenType::OpBraceLeft))
	{
		return ParseJSObject(lex);
	}
	else if (tk.is_identifier())
	{
		if (tk.get_string() == L"true" || tk.get_string() == L"false")
		{
			return new JsonItemBool(tk.get_string() == L"true");
		}
		else if (tk.get_string() == L"null")
		{
			return new JsonItem();
		}
	}

	return nullptr;
}

JsonItem* ParseJSArray(CLex& lex)
{
	JsonItemArray* array = new JsonItemArray;
	CToken tk = lex.get_token_no_lfeed();
	
	while (!tk.is_operator(CTokenType::OpBracketRight))
	{
		lex.put_back(tk);
		JsonItem* item = ParseJSItem(lex);
		if (item == nullptr)
		{
			delete array;
			return nullptr;
		}

		array->push(item);

		tk = lex.get_token_no_lfeed();

		if (tk.is_operator(CTokenType::OpBracketRight))
		{
			return array;
		}

		if (!tk.is_operator(CTokenType::OpComma))
		{
			delete array;
			return nullptr;
		}

		tk = lex.get_token_no_lfeed();
	}

	return array;
}

JsonItem* ParseJSObject(CLex& lex)
{
	JsonItemObject* dict = new JsonItemObject;
	CToken tk = lex.get_token_no_lfeed();

	while (!tk.is_operator(CTokenType::OpBraceRight))
	{
		std::wstring name;

		if (tk.is_identifier() || tk.is_string())
		{
			name = tk.get_string();
		}
		else
		{
			delete dict;
			return nullptr;
		}

		tk = lex.get_token_no_lfeed();
		if (!tk.is_operator(CTokenType::OpColon))
		{
			delete dict;
			return nullptr;
		}

		JsonItem* item = ParseJSItem(lex);
		if (item == nullptr)
		{
			delete dict;
			return nullptr;
		}

		dict->add_child(name, item);
		tk = lex.get_token_no_lfeed();
		if (tk.is_operator(CTokenType::OpBraceRight))
		{
			return dict;
		}

		if (!tk.is_operator(CTokenType::OpComma))
		{
			delete dict;
			return nullptr;
		}

		tk = lex.get_token_no_lfeed();
	}

	return dict;
}

JsonItemPtr ParseJSCode(const std::wstring& json)
{
	if (json.empty())
	{
		return nullptr;
	}

	CLex lex;
	if (!lex.load_data(json))
	{
		return nullptr;
	}

	return JsonItemPtr(ParseJSItem(lex));
}
Marcelxx 2018-04-28
  • 打赏
  • 举报
回复
libjson了解一下?
赵4老师 2018-04-27
  • 打赏
  • 举报
回复
引用 13 楼 iloveyou418 的回复:
[quote=引用 3 楼 zhao4zhong1 的回复:] http://www.json.org
+1 看看学学抄抄~ok了 [/quote]
eeeeelin 2018-04-27
  • 打赏
  • 举报
回复
看cJSON源码,自己用C++封装一下
CT8100 2018-04-27
  • 打赏
  • 举报
回复
引用 3 楼 zhao4zhong1 的回复:
http://www.json.org
+1 看看学学抄抄~ok了
Really_want 2018-04-26
  • 打赏
  • 举报
回复
引用 5 楼 hefashion0190 的回复:
[quote=引用 4 楼 housecarl 的回复:] 非常理解楼主的想法。因为一开始我也是这么想的,然后发现太麻烦了,就用了公共库。 推荐楼主使用rapidjson或者jsoncpp
+1[/quote] +1
mLee79 2018-04-25
  • 打赏
  • 举报
回复
JSON 这么规范的, 带个栈的正规文法就可以描述, 用不着BNF, 正则就可以了 ..
剑文文 2018-04-25
  • 打赏
  • 举报
回复
jsoncpp 好用,我一直用这个
mxway 2018-04-24
  • 打赏
  • 举报
回复
cjson几百行代码
starytx 2018-04-24
  • 打赏
  • 举报
回复
如果你只是要使用json,这个轮子造的没有一点性价比,可以使用的json库多得很,自己造太累,如果你是做研究,祝你成功
FoolCarpe 2018-04-24
  • 打赏
  • 举报
回复
引用 4 楼 housecarl 的回复:
非常理解楼主的想法。因为一开始我也是这么想的,然后发现太麻烦了,就用了公共库。 推荐楼主使用rapidjson或者jsoncpp
+1
zilaishuichina 2018-04-24
  • 打赏
  • 举报
回复
EBNF范式 boost的spirit库
轻箬笠 2018-04-24
  • 打赏
  • 举报
回复
非常理解楼主的想法。因为一开始我也是这么想的,然后发现太麻烦了,就用了公共库。 推荐楼主使用rapidjson或者jsoncpp
ztenv 版主 2018-04-24
  • 打赏
  • 举报
回复
jsoncpp
赵4老师 2018-04-21
  • 打赏
  • 举报
回复
幻夢之葉 2018-04-20
  • 打赏
  • 举报
回复
找个开源的简易解析Json的源代码
srhouyu 2018-04-20
  • 打赏
  • 举报
回复
你要是从没有搞过解析器,那么这并不是简单事,两天恐怕不行。 想简单的,看看这个问答: https://www.zhihu.com/question/24640264 想系统的,看看《编程语言实现模式》。
内容概要:本文深入讲解了C++17的核心新特性及其在实际开发中的应用。重点介绍了结构化绑定、if constexpr编译期条件判断和折叠表达式三大语言增强特性,帮助开发者简化代码、提升性能与可读性。同时详细阐述了标准库新增的重要组件:std::optional用于安全处理可能为空的值,std::variant实现类型安全的联合体,std::any支持任意类型的存储与访问。文章进一步通过实战技巧展示这些特性在模板优化、容器遍历和多类型处理中的高效应用,并以“灵活数据解析器”项目综合运用上述技术,实现对JSON等多种格式的安全、高效解析,最后强调了解析效率测试与跨平台兼容性验证的重要性。 适合人群:具备一定C++基础,熟悉C++11/14特性的中高级开发者,尤其是从事高性能系统开发、库设计或希望深入掌握现代C++编程的工程师(工作年限约2-5年)。 使用场景及目标:①掌握C++17关键特性以提升代码质量与运行效率;②学习如何利用std::optional、std::variant和std::any构建类型安全、健壮的程序;③理解现代C++在实际项目中(如数据解析)的综合应用方式。 阅读建议:此资源不仅介绍语法特性,更注重实战与架构设计思想,建议读者结合代码示例动手实践,尤其应尝试在不同编译器和平台上运行项目代码,深入理解C++17带来的编程范式升级。
内容概要:本文详细介绍了一个基于C++的在线天气查询系统的设计与实现,涵盖了项目背景、目标、挑战及解决方案,并提供了系统的整体架构和核心模块的代码示例。系统采用模块化设计,包括数据获取、解析、存储、业务逻辑和用户交互五大模块,利用libcurl进行HTTP请求,RapidJSON解析JSON数据,支持实时天气查询与历史数据管理,具备跨平台兼容性、高稳定性和可扩展性。文中还展示了关键功能的C++实现代码,如天气数据获取与结构化解析,体现了网络通信、数据处理与系统设计的综合应用。; 适合人群:具备C++编程基础,熟悉网络编程、JSON/XML数据处理及多线程技术的开发者,适合有一定项目经验的中初级程序员或计算机相关专业学生; 使用场景及目标:①学习如何在C++中调用外部API并处理返回数据;②掌握天气数据的实时获取、解析与结构化存储方法;③理解模块化系统架构设计,提升跨平台应用开发能力; 阅读建议:建议结合代码示例深入理解各模块协作机制,动手实践网络请求、数据解析与错误处理等关键技术环节,并可在此基础上拓展图形界面或增加数据可视化功能以增强系统实用性。

65,208

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧