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


前言

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文件

  • 12
    点赞
  • 72
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
解析JSON文件,可以使用json-c库,具体步骤如下: 1. 引入json-c库的头文件 ```c #include <json-c/json.h> ``` 2. 读取JSON文件内容 ```c FILE *fp = fopen("filename.json", "r"); if (fp == NULL) { printf("Failed to open file\n"); return -1; } char buffer[1024]; fread(buffer, 1, 1024, fp); fclose(fp); ``` 3. 解析JSON文件内容 ```c struct json_object *json_obj = json_tokener_parse(buffer); ``` 4. 获取JSON对象的值 ```c // 获取字符串类型的值 const char *str_value; json_object_object_get_ex(json_obj, "key", &str_value); printf("%s\n", str_value); // 获取整数类型的值 int int_value; json_object_object_get_ex(json_obj, "key", &int_value); printf("%d\n", int_value); // 获取数组类型的值 struct json_object *arr_obj; json_object_object_get_ex(json_obj, "key", &arr_obj); int arr_len = json_object_array_length(arr_obj); for (int i = 0; i < arr_len; i++) { struct json_object *item = json_object_array_get_idx(arr_obj, i); // 处理数组项 } ``` 完整的示例代码如下: ```c #include <stdio.h> #include <json-c/json.h> int main() { FILE *fp = fopen("example.json", "r"); if (fp == NULL) { printf("Failed to open file\n"); return -1; } char buffer[1024]; fread(buffer, 1, 1024, fp); fclose(fp); struct json_object *json_obj = json_tokener_parse(buffer); const char *str_value; json_object_object_get_ex(json_obj, "name", &str_value); printf("name: %s\n", str_value); int age_value; json_object_object_get_ex(json_obj, "age", &age_value); printf("age: %d\n", age_value); struct json_object *hobby_arr_obj; json_object_object_get_ex(json_obj, "hobbies", &hobby_arr_obj); int hobby_arr_len = json_object_array_length(hobby_arr_obj); printf("hobbies:\n"); for (int i = 0; i < hobby_arr_len; i++) { struct json_object *item = json_object_array_get_idx(hobby_arr_obj, i); printf("- %s\n", json_object_get_string(item)); } json_object_put(json_obj); return 0; } ``` 需要注意的是,使用完json对象后,需要调用`json_object_put`函数释放内存。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值