C语言中解析JSON字符串的实用指南**
在C语言中处理JSON字符串是一个常见的需求,尤其是在与Web服务交互、配置文件解析或数据交换等场景,C语言本身并没有内置对JSON格式的原生支持,因此我们需要借助第三方库来轻松解析JSON字符串,本文将介绍几种流行的C语言JSON库,并以其中两个为例,展示如何解析JSON字符串。
为什么在C中解析JSON需要库?
JSON是一种轻量级的数据交换格式,它易于人阅读和编写,也易于机器解析和生成,其结构包括对象(用花括号表示)、数组(用方括号[]表示)、字符串、数字、布尔值和null,C语言是过程式的,没有直接对应JSON对象和数组的数据结构(如Python的字典或列表),手动解析需要处理字符串分割、类型转换、内存管理等诸多细节,既繁琐又容易出错,使用成熟的JSON库是明智之举。
流行的C语言JSON库
- cJSON:一个轻量量级的、单文件的C语言JSON解析器,它易于集成,API简单直观,非常适合嵌入式系统或对内存占用有要求的项目。
- Jansson:一个功能丰富、纯C的JSON库,提供了类型安全的API,错误处理机制较好,性能也不错。
- ujson (Ultra JSON):以高性能著称,适合需要快速解析大量JSON数据的场景。
- json-c:另一个广泛使用的开源库,提供了一系列函数来创建、解析和操作JSON数据。
本文将重点介绍cJSON和Jansson的使用方法,因为它们对于初学者来说相对友好且文档齐全。
使用cJSON库解析JSON字符串
cJSON的核心思想是将JSON字符串解析成一个cJSON对象树,你可以遍历这棵树来获取所需的数据。
步骤1:获取并集成cJSON
- 从cJSON的GitHub仓库(https://github.com/DaveGamble/cJSON)下载源代码。
- 将
cJSON.h和cJSON.c文件添加到你的项目中。 - 编译时链接
cJSON.c。
步骤2:解析JSON字符串并获取数据
假设我们有以下JSON字符串:
{
"name": "John Doe",
"age": 30,
"isStudent": false,
"courses": ["Math", "Science", "History"],
"address": {
"street": "123 Main St",
"city": "New York"
}
}
示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cJSON.h"
int main() {
const char *json_string = "{"
"\"name\": \"John Doe\","
"\"age\": 30,"
"\"isStudent\": false,"
"\"courses\": [\"Math\", \"Science\", \"History\"],"
"\"address\": {"
"\"street\": \"123 Main St\","
"\"city\": \"New York\""
"}"
"}";
// 1. 解析JSON字符串
cJSON *root = cJSON_Parse(json_string);
if (root == NULL) {
const char *error_ptr = cJSON_GetErrorPtr();
if (error_ptr != NULL) {
fprintf(stderr, "Error before: %s\n", error_ptr);
}
return 1;
}
// 2. 获取字符串值
cJSON *name = cJSON_GetObjectItemCaseSensitive(root, "name");
if (cJSON_IsString(name) && (name->valuestring != NULL)) {
printf("Name: %s\n", name->valuestring);
}
// 3. 获取数值
cJSON *age = cJSON_GetObjectItemCaseSensitive(root, "age");
if (cJSON_IsNumber(age)) {
printf("Age: %d\n", age->valueint);
}
// 4. 获取布尔值
cJSON *isStudent = cJSON_GetObjectItemCaseSensitive(root, "isStudent");
if (cJSON_IsBool(isStudent)) {
printf("Is Student: %s\n", cJSON_IsTrue(isStudent) ? "true" : "false");
}
// 5. 获取数组
cJSON *courses = cJSON_GetObjectItemCaseSensitive(root, "courses");
if (cJSON_IsArray(courses)) {
int course_count = cJSON_GetArraySize(courses);
printf("Courses (%d):\n", course_count);
for (int i = 0; i < course_count; i++) {
cJSON *course = cJSON_GetArrayItem(courses, i);
if (cJSON_IsString(course) && (course->valuestring != NULL)) {
printf(" - %s\n", course->valuestring);
}
}
}
// 6. 获取嵌套对象
cJSON *address = cJSON_GetObjectItemCaseSensitive(root, "address");
if (cJSON_IsObject(address)) {
cJSON *street = cJSON_GetObjectItemCaseSensitive(address, "street");
cJSON *city = cJSON_GetObjectItemCaseSensitive(address, "city");
if (cJSON_IsString(street) && (street->valuestring != NULL) &&
cJSON_IsString(city) && (city->valuestring != NULL)) {
printf("Address: %s, %s\n", street->valuestring, city->valuestring);
}
}
// 7. 释放内存
cJSON_Delete(root);
return 0;
}
cJSON关键点:
cJSON_Parse():解析JSON字符串,返回cJSON对象指针。cJSON_GetObjectItemCaseSensitive():根据键名获取对象中的项(区分大小写)。cJSON_IsString(),cJSON_IsNumber(),cJSON_IsBool(),cJSON_IsArray(),cJSON_IsObject():类型检查宏。valuestring,valueint,valuedouble:获取对应类型的值。cJSON_GetArraySize():获取数组大小。cJSON_GetArrayItem():获取数组中的指定项。cJSON_Delete():释放解析后的cJSON对象树及其所有子项,防止内存泄漏。
使用Jansson库解析JSON字符串
Jansson提供了更类型化的API,错误处理也更为完善。
步骤1:获取并集成Jansson
- 从Jansson的官方网站(https://github.com/akheron/jansson)下载源代码并编译安装,或使用包管理器(如
apt-get install libjansson-dev)。 - 在编译时链接Jansson库(
gcc your_program.c -ljansson)。
步骤2:解析JSON字符串并获取数据
使用相同的JSON字符串示例:
示例代码:
#include <stdio.h>
#include <jansson.h>
int main() {
const char *json_string = "{"
"\"name\": \"John Doe\","
"\"age\": 30,"
"\"isStudent\": false,"
"\"courses\": [\"Math\", \"Science\", \"History\"],"
"\"address\": {"
"\"street\": \"123 Main St\","
"\"city\": \"New York\""
"}"
"}";
json_error_t error;
// 1. 解析JSON字符串
json_t *root = json_loads(json_string, 0, &error);
if (!root) {
fprintf(stderr, "Error on line %d: %s\n", error.line, error.text);
return 1;
}
// 2. 获取字符串值
json_t *name = json_object_get(root, "name");
if (json_is_string(name)) {
printf("Name: %s\n", json_string_value(name));
}
// 3. 获取数值
json_t *age = json_object_get(root, "age");
if (json_is_integer(age)) {
printf("Age: %d\n", json_integer_value(age));
}
// 4. 获取布尔值
json_t *isStudent = json_object_get(root, "isStudent");
if (json_is_boolean(isStudent)) {
printf("Is Student: %s\n", json_boolean_value(isStudent) ? "true" : "false");
}
// 5. 获取数组
json_t *courses = json_object_get(root, "courses");
if (json_is_array(courses)) {
size_t course_count = json_array_size(courses);
printf("Courses (%zu):\n", course_count);
for (size_t i = 0; i < course_count; i++) {
json_t *course = json_array_get(courses, i);
if (json_is_string(course)) {
printf(" - %s\n", json_string_value(course));
}
}
}
// 6. 获取嵌套对象
json_t *address = json_object_get(root, "address");
if (json_is_object(address)) {
json_t *street = json_object_get(address, "street");
json_t *city =抖音足球直播
抖音足球直播
企鹅直播
企鹅直播
足球直播
爱奇艺直播
爱奇艺足球直播
足球直播
足球直播
iqiyi直播
足球直播
足球直播
QQ足球直播
QQ足球直播
足球直播
足球直播
QQ足球直播
QQ足球直播
足球直播
足球直播
快连
快连
快连
快连下载
快连
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
新浪足球直播
新浪足球直播
足球直播
足球直播
有道翻译
有道翻译
有道翻译
有道翻译
wps
wps
wps
wps
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
新浪足球直播
新浪足球直播
足球直播
足球直播



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