使用jsmn解析JSON数据的入门指南
2025-07-09 03:48:05作者:董斯意
什么是jsmn
jsmn是一个轻量级的JSON解析器,特别适合嵌入式系统和资源受限的环境。它不分配内存,不依赖任何标准库以外的库,使得它非常小巧高效。jsmn的设计哲学是"最小但足够",它只做JSON解析这一件事,但做得很好。
示例代码解析
这个简单的示例展示了如何使用jsmn来解析一个已知结构的JSON字符串。让我们逐步分析这个示例的工作原理。
1. 初始化解析器
jsmn_parser p;
jsmntok_t t[128]; /* 我们预计不超过128个token */
jsmn_init(&p);
首先我们初始化一个jsmn解析器对象,并准备一个token数组来存储解析结果。这里预设了128个token的空间,对于简单JSON通常足够。
2. 解析JSON字符串
r = jsmn_parse(&p, JSON_STRING, strlen(JSON_STRING), t, sizeof(t)/sizeof(t[0]));
调用jsmn_parse
函数进行实际解析,传入:
- 解析器对象
- JSON字符串及其长度
- token数组及其容量
返回值r表示解析出的token数量,如果为负则表示错误。
3. 验证顶层元素
if (r < 1 || t[0].type != JSMN_OBJECT) {
printf("Object expected\n");
return 1;
}
检查顶层元素是否为对象类型(JSON对象),这是我们对这个特定JSON结构的预期。
4. 遍历解析结果
核心部分是一个循环,遍历所有token来提取我们需要的数据:
for (i = 1; i < r; i++) {
if (jsoneq(JSON_STRING, &t[i], "user") == 0) {
printf("- User: %.*s\n", t[i+1].end - t[i+1].start,
JSON_STRING + t[i+1].start);
i++;
}
// 其他字段处理...
}
jsoneq
是一个辅助函数,用于比较JSON中的字符串是否与给定字符串匹配。当找到一个键时,它的值通常就在下一个token中。
关键概念解析
Token类型
jsmn定义了以下几种token类型:
JSMN_PRIMITIVE
:true/false/null/数字JSMN_STRING
:字符串JSMN_OBJECT
:JSON对象JSMN_ARRAY
:JSON数组
Token结构
每个token包含以下信息:
type
:token类型start
/end
:在原始JSON字符串中的位置size
:对于对象表示键值对数量,对于数组表示元素数量
解析流程
- 初始化解析器
- 调用
jsmn_parse
获取token列表 - 遍历token列表,根据token类型和位置提取数据
- 注意token之间的父子关系(对象/数组与其内容)
实际应用建议
- 错误处理:总是检查
jsmn_parse
的返回值,负值表示错误 - 内存管理:预先分配足够的token空间,复杂JSON可能需要更多token
- 类型检查:访问值前确认token类型是否符合预期
- 性能考虑:对于已知结构的JSON,可以优化解析流程,如示例所示
为什么选择jsmn
- 轻量级:非常适合嵌入式系统
- 零内存分配:解析过程不动态分配内存
- 简单API:学习曲线平缓
- 可移植性:纯C实现,无外部依赖
这个简单示例展示了jsmn的基本用法,对于更复杂的JSON结构,原理是相同的,只是需要更细致的token遍历逻辑。理解了这个示例,你就掌握了使用jsmn解析JSON的核心方法。