C语言解析json--超详细,接口、参数全覆盖,一看就会

本文详细介绍了如何在C语言中使用cJSON库解析JSON数据。从下载cJSON库文件,到调用cJSON_Parse解析JSON字符串,再到通过cJSON接口获取并检查各个对象、数组及其元素,最后展示了详细的测试代码示例。通过这个教程,读者可以掌握C语言中JSON解析的基本操作。
摘要由CSDN通过智能技术生成


前言

c语言生成json在我之前的博客有详细说明,想学习的同学可以跳过去看,这篇博客介绍c语言解析json,和生成过程相反,解析json的目的是从json文件中解析出里面的对象及对象的值。


一、json是什么

JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。-- 来自百度百科

二、C语言解析json

1.下载cJSON库文件

cJSON库文件一共两个文件:cJSON.h和cJSON.c。这两个文件可以从李老师的AWTK开源项目中可以找到:https://github.com/zlgopen/awtk/blob/master/3rd/cjson。

2.使用cJSON接口解析json

//aidl接口示例:
interface IMinistro
{
    void requestLoader(in IMinistroCallback callback, in Bundle parameters);
}
//aidl接口的json表示:
{
	"interface ": 
	{
		"interface_name": "IMinistro",
		"function_array": 
		[
			"return_type": "void",
			"function_name": "requestLoader",
			"param_list": 
			[
				{
					"param_tag":  "in",
					"param_type": "IMinistroCallback",
					"param_name": "callback"
				}
			]
		]
	}
}
//cJSON结构定义:
/* The cJSON structure: */
typedef struct cJSON
{
    /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
    struct cJSON *next;
    struct cJSON *prev;
    /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
    struct cJSON *child;

    /* The type of the item, as above. */
    int type;

    /* The item's string, if type==cJSON_String  and type == cJSON_Raw */
    char *valuestring;
    /* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
    int valueint;
    /* The item's number, if type==cJSON_Number */
    double valuedouble;

    /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
    char *string;
} cJSON;

//以下代码是我在gtest工程的测试代码,非常详细,解析json文件用到的接口基本上都有了:
	//C语言解析上述json
	//out是上述json字符串
	//第一步:调用cJSON_Parse开始解析json文件,获得json根节点
	cJSON* root = cJSON_Parse(out);
	ASSERT_EQ(TRUE, root != NULL);
	ASSERT_EQ(TRUE, root->child != NULL);
	
	//第二步,按子节点的名称取出子节点对象interface 
	cJSON* interface = cJSON_GetObjectItem(root, "interface");
	ASSERT_EQ(TRUE, interface != NULL);
	ASSERT_EQ(TRUE, cJSON_IsObject(interface));
	
	//从interface 对象中,继续按名称取出其子节点对象interface_name 
	//通过interface_name->string可以得到节点名
	//通过interface_name->valuestring可以得到节点值的字符串表示方式
	cJSON* interface_name = cJSON_GetObjectItem(interface, "interface_name");
	ASSERT_EQ(TRUE, strcmp(interface_name->string, "interface_name") == 0);
	ASSERT_EQ(TRUE, strcmp(interface_name->valuestring, "IMinistro") == 0);
	
	//从interface 对象中,继续按名称取出其子节点对象function_array 
	//cJSON_IsArray函数可以判断function_array是否是一个数组类型的对象
	//cJSON_GetArraySize可以获取数组的大小
	cJSON* function_array = cJSON_GetObjectItem(interface, "function_array");
	ASSERT_EQ(TRUE, function_array != NULL);
	ASSERT_EQ(TRUE, cJSON_IsArray(function_array));
	ASSERT_EQ(2, cJSON_GetArraySize(function_array));
	
	//cJSON_GetArrayItem获取对应下标的数组元素
	cJSON* function_0 = cJSON_GetArrayItem(function_array, 0);
	ASSERT_EQ(TRUE, function_0 != NULL);
	ASSERT_EQ(TRUE, cJSON_IsObject(function_0));
	
	//cJSON_GetObjectItem可以获得对象的子对象节点
	cJSON* return_type = cJSON_GetObjectItem(function_0, "return_type");
	ASSERT_EQ(TRUE, return_type != NULL);
	ASSERT_EQ(TRUE, strcmp(return_type->string, "return_type") == 0);
	ASSERT_EQ(TRUE, strcmp(return_type->valuestring, "void") == 0);
	
	cJSON* function_name = cJSON_GetObjectItem(function_0, "function_name");
	ASSERT_EQ(TRUE, function_name != NULL);
	ASSERT_EQ(TRUE, strcmp(function_name->string, "function_name") == 0);
	ASSERT_EQ(TRUE, strcmp(function_name->valuestring, "requestLoader") == 0);
	
	cJSON* param_list = cJSON_GetObjectItem(function_0, "param_list");
	ASSERT_EQ(TRUE, param_list != NULL);
	ASSERT_EQ(TRUE, cJSON_IsArray(param_list));
	ASSERT_EQ(2, cJSON_GetArraySize(param_list));
	
	cJSON* param_0 = cJSON_GetArrayItem(param_list, 0);
	ASSERT_EQ(TRUE, param_0 != NULL);
	ASSERT_EQ(TRUE, cJSON_IsObject(param_0));
	
	cJSON* tag = cJSON_GetObjectItem(param_0, "param_tag");
	ASSERT_EQ(TRUE, tag != NULL);
	ASSERT_EQ(TRUE, strcmp(tag->string, "param_tag") == 0);
	ASSERT_EQ(TRUE, strcmp(tag->valuestring, "in") == 0);
	
	cJSON* param_type = cJSON_GetObjectItem(param_0, "param_type");
	ASSERT_EQ(TRUE, param_type != NULL);
	ASSERT_EQ(TRUE, strcmp(param_type->string, "param_type") == 0);
	ASSERT_EQ(TRUE, strcmp(param_type->valuestring, "IMinistroCallback") == 0);
	
	cJSON* param_name = cJSON_GetObjectItem(param_0, "param_name");
	ASSERT_EQ(TRUE, param_name != NULL);
	ASSERT_EQ(TRUE, strcmp(param_name->string, "param_name") == 0);
	ASSERT_EQ(TRUE, strcmp(param_name->valuestring, "callback") == 0);
	
	//释放资源
	cJSON_Delete(root);

总结

知识的汇总:
cJSON_Parse: 解析json,获得根节点
cJSON_Delete:释放资源 cJSON_GetObjectItem:根据子节点名称获取子节点对象
cJSON_IsArray:判断节点对象是否是数组
cJSON_GetArraySize:获取数组大小
cJSON_GetArrayItem:按下标获取元素
tag->string:tag对象名
tag->valuestring:tag对象字符串形式的值
tag->valueint:tag对象int形式的值
tag->valuedouble:tag对象字double形式的值

获取cJson文件

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值