JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,常用于在客户端和服务器之间传输数据。由于它是一种文本格式,易于阅读和编写,并且可以在各种编程语言之间进行解析和生成数据,因此它成为了一种普遍的数据交换格式。
1.JSON基础
JSON由键值对构成,键名必须是字符串,值可以是任意有效的JSON数据类型。
数据包围在大括号 {} 中,键值对之间用逗号 , 分隔。
2.CJOSN配置
CJSON是一个使用C语言编写的JSON数据解析器,具有超轻便,可移植,单文件的特点,使用MIT开源协议。
使用CJSON时,你需要确保将以下两个文件包含在你的项目目录中:
- cJSON.h
- cJSON.c
然后将 cJSON.h 编译到你的项目中,以实现JSON数据的解析和处理功能。
下载地址:https://github.com/DaveGamble/cJSON/releases
3. JSON解析方法
在实际应用中,可以采用以下几种常见的JSON解析方法:
- 逐级解析:从JSON的最外层开始,逐级解析每个键值对或数组元素。
- 递归解析:递归地处理嵌套结构,直到整个JSON文档被解析完毕。
4. 实际应用示例
示例 1:逐级解析复杂的 JSON 数据以获取特定数据
#include <stdio.h>
#include <string.h>
#include "cJSON.h"
int main() {
const char *json_str = "{"
"\"name\": \"John Doe\","
"\"age\": 30,"
"\"address\": {"
"\"street\": \"123 Main St\","
"\"city\": \"Anytown\","
"\"state\": \"CA\","
"\"postalCode\": \"12345\""
"}"
"}";
cJSON *root = cJSON_Parse(json_str);
if (root == NULL) {
printf("Error parsing JSON: %s\n", cJSON_GetErrorPtr());
return 1;
}
cJSON *name = cJSON_GetObjectItem(root, "name");
if (cJSON_IsString(name) && (name->valuestring != NULL)) {
printf("Name: %s\n", name->valuestring);
}
cJSON *age = cJSON_GetObjectItem(root, "age");
if (cJSON_IsNumber(age)) {
printf("Age: %d\n", age->valueint);
}
cJSON *address = cJSON_GetObjectItem(root, "address");
if (cJSON_IsObject(address)) {
cJSON *street = cJSON_GetObjectItem(address, "street");
cJSON *city = cJSON_GetObjectItem(address, "city");
cJSON *state = cJSON_GetObjectItem(address, "state");
cJSON *postalCode = cJSON_GetObjectItem(address, "postalCode");
if (cJSON_IsString(street) && cJSON_IsString(city) &&
cJSON_IsString(state) && cJSON_IsString(postalCode)) {
printf("Address: %s, %s, %s %s\n", street->valuestring, city->valuestring,
state->valuestring, postalCode->valuestring);
}
}
cJSON_Delete(root);
return 0;
}
示例 2:递归形式读取所有数据
#include <stdio.h>
#include <string.h>
#include "cJSON.h"
void print_json_recursive(cJSON *item, const char *parent_key) {
// Check if item is an object
if (item->type == cJSON_Object) {
// Print each key-value pair
cJSON *child = item->child;
while (child != NULL) {
// Construct key based on parent key (if available)
char *key;
if (parent_key != NULL) {
key = cJSON_AddItemToObject(NULL, parent_key, cJSON_CreateString(child->string));
} else {
key = child->string;
}
// Recursively print value
print_json_recursive(child, key);
child = child->next;
}
} else if (item->type == cJSON_String) {
// Print string value
printf("%s: %s\n", parent_key, item->valuestring);
} else if (item->type == cJSON_Number) {
// Print number value
printf("%s: %g\n", parent_key, item->valuedouble);
} else if (item->type == cJSON_Array) {
// Handle array (if needed)
} else {
// Handle other types as needed
}
}
int main() {
const char *json_str = "{"
"\"name\": \"John Doe\","
"\"age\": 30,"
"\"address\": {"
"\"street\": \"123 Main St\","
"\"city\": \"Anytown\","
"\"state\": \"CA\","
"\"postalCode\": \"12345\""
"}"
"}";
cJSON *root = cJSON_Parse(json_str);
if (root == NULL) {
printf("Error parsing JSON: %s\n", cJSON_GetErrorPtr());
return 1;
}
// Start recursive printing from root
print_json_recursive(root, NULL);
cJSON_Delete(root);
return 0;
}
5.总结:
在实际应用中,通过cJSON库可以实现对复杂JSON数据的解析和处理,例如逐级解析或递归解析以获取特定数据。解析过程中需要注意处理数据类型的匹配和错误处理,确保程序的稳定性和可靠性。