C语言中如何遍历JSON数组:实用指南与代码示例
在C语言中处理JSON数据时,遍历JSON数组是一个常见且重要的操作,由于C语言本身没有内置的JSON解析功能,我们需要借助第三方库来实现这一功能,本文将介绍如何使用流行的C语言JSON库(如cJSON、Jansson等)来遍历JSON数组,并提供详细的代码示例。
使用cJSON库遍历JSON数组
cJSON是一个轻量级的C语言JSON解析器,它提供了简单易用的API来处理JSON数据,下面我们将详细介绍如何使用cJSON遍历JSON数组。
准备工作
确保你已经安装了cJSON库,你可以从官方GitHub仓库下载源代码,并将其集成到你的项目中。
解析JSON字符串
假设我们有以下JSON字符串,其中包含一个数组:
const char *json_string = "[\"apple\", \"banana\", \"cherry\", 42, true]";
解析JSON并获取数组
使用cJSON解析这个字符串并获取数组对象:
#include <stdio.h>
#include <stdlib.h>
#include "cJSON.h"
int main() {
const char *json_string = "[\"apple\", \"banana\", \"cherry\", 42, true]";
// 解析JSON字符串
cJSON *json = cJSON_Parse(json_string);
if (json == NULL) {
const char *error_ptr = cJSON_GetErrorPtr();
if (error_ptr != NULL) {
fprintf(stderr, "Error before: %s\n", error_ptr);
}
return 1;
}
// 检查是否是数组
if (!cJSON_IsArray(json)) {
fprintf(stderr, "JSON is not an array\n");
cJSON_Delete(json);
return 1;
}
// 遍历数组
cJSON *item = NULL;
cJSON_ArrayForEach(item, json) {
// 根据值的类型进行不同的处理
if (cJSON_IsString(item)) {
printf("String: %s\n", item->valuestring);
} else if (cJSON_IsNumber(item)) {
printf("Number: %d\n", item->valueint);
} else if (cJSON_IsBool(item)) {
printf("Boolean: %s\n", cJSON_IsTrue(item) ? "true" : "false");
} else {
printf("Other type\n");
}
}
// 释放内存
cJSON_Delete(json);
return 0;
}
代码解释
- 解析JSON字符串:使用
cJSON_Parse()函数将JSON字符串解析为cJSON对象。 - 检查是否为数组:使用
cJSON_IsArray()确保解析后的对象是一个数组。 - 遍历数组:使用
cJSON_ArrayForEach宏遍历数组中的每个元素,这个宏会自动处理数组的长度和索引。 - 处理不同类型的值:使用
cJSON_IsString()、cJSON_IsNumber()、cJSON_IsBool()等函数检查每个元素的类型,并相应地处理它们。 - 释放内存:使用
cJSON_Delete()释放解析过程中分配的内存。
使用Jansson库遍历JSON数组
Jansson是另一个流行的C语言JSON库,下面是如何使用Jansson遍历JSON数组的示例:
#include <stdio.h>
#include <jansson.h>
int main() {
const char *json_string = "[\"apple\", \"banana\", \"cherry\", 42, true]";
json_error_t error;
json_t *root = json_loads(json_string, 0, &error);
if (!root) {
fprintf(stderr, "JSON error on line %d: %s\n", error.line, error.text);
return 1;
}
if (!json_is_array(root)) {
fprintf(stderr, "JSON is not an array\n");
json_decref(root);
return 1;
}
size_t index;
json_t *value;
json_array_foreach(root, index, value) {
if (json_is_string(value)) {
printf("String: %s\n", json_string_value(value));
} else if (json_is_integer(value)) {
printf("Number: %d\n", json_integer_value(value));
} else if (json_is_boolean(value)) {
printf("Boolean: %s\n", json_is_true(value) ? "true" : "false");
} else {
printf("Other type\n");
}
}
json_decref(root);
return 0;
}
处理嵌套数组
如果JSON数组中包含嵌套的数组或对象,我们需要递归地遍历它们,以下是一个处理嵌套数组的示例:
void print_json_value(json_t *value, int indent) {
if (json_is_string(value)) {
printf("%*sString: %s\n", indent, "", json_string_value(value));
} else if (json_is_integer(value)) {
printf("%*sNumber: %d\n", indent, "", json_integer_value(value));
} else if (json_is_boolean(value)) {
printf("%*sBoolean: %s\n", indent, "", json_is_true(value) ? "true" : "false");
} else if (json_is_array(value)) {
printf("%*sArray:\n", indent, "");
size_t index;
json_t *item;
json_array_foreach(value, index, item) {
print_json_value(item, indent + 4);
}
} else if (json_is_object(value)) {
printf("%*sObject:\n", indent, "");
const char *key;
json_t *val;
json_object_foreach(value, key, val) {
printf("%*sKey: %s\n", indent + 4, "", key);
print_json_value(val, indent + 8);
}
}
}
int main() {
const char *json_string = "[\"apple\", [\"nested\", 123], {\"key\": \"value\"}]";
json_error_t error;
json_t *root = json_loads(json_string, 0, &error);
if (!root) {
fprintf(stderr, "JSON error on line %d: %s\n", error.line, error.text);
return 1;
}
if (!json_is_array(root)) {
fprintf(stderr, "JSON is not an array\n");
json_decref(root);
return 1;
}
print_json_value(root, 0);
json_decref(root);
return 0;
}
在C语言中遍历JSON数组主要依赖于第三方JSON库,本文介绍了使用cJSON和Jansson两个流行库的方法:
- cJSON:使用
cJSON_ArrayForEach宏遍历数组,通过cJSON_Is*系列函数检查值的类型。 - Jansson:使用
json_array_foreach宏遍历数组,通过json_is_*系列函数检查值的类型。
对于嵌套的JSON结构,可以采用递归的方式进行处理,无论使用哪个库,记住在完成操作后都要释放分配的内存,避免内存泄漏。
选择哪个库取决于你的具体需求和个人偏好,cJSON更加轻量级,而Jansson提供了更丰富的功能和更好的错误处理机制,希望本文能帮助你在C语言项目中顺利地遍历JSON数组。



还没有评论,来说两句吧...