c语言如何解析json

来源:站长论坛作者:小团团头衔:草根站长
导读:本期聚焦于小伙伴创作的《c语言如何解析json》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《c语言如何解析json》有用,将其分享出去将是对创作者最好的鼓励。

c语言本身没有内置的json解析相关的标准库,要实现json数据的解析,通常需要借助第三方开源库,其中cJSON是应用最广泛、轻量且易用的选择,它仅由两个文件组成,适配绝大多数c语言开发环境。

c语言如何解析json

cJSON库的基础准备

首先需要获取cJSON的源码,它包含两个文件:cJSON.h和cJSON.c,将其添加到自己的项目工程中即可使用。如果是Linux环境,也可以通过包管理器安装对应的开发包,安装完成后在代码中引入头文件就可以调用相关接口。

#include <stdio.h>
#include <stdlib.h>
// 引入cJSON头文件
#include "cJSON.h"

int main() {
    // 后续解析逻辑会在这里编写
    return 0;
}

解析基础类型的json数据

json的基础类型包括字符串、数字、布尔值、null,cJSON提供了对应的接口来获取这些类型的值,解析前需要先调用cJSON_Parse函数将json字符串转换为cJSON对象,解析完成后要记得释放内存。

解析字符串和数字示例

假设我们有一个简单的json字符串,包含用户名和年龄两个字段,解析代码如下:

#include <stdio.h>
#include <stdlib.h>
#include "cJSON.h"

int main() {
    // 待解析的json字符串
    char *json_str = "{"name":"张三","age":25}";
    // 将json字符串解析为cJSON对象
    cJSON *root = cJSON_Parse(json_str);
    if (root == NULL) {
        printf("json解析失败,错误位置:%sn", cJSON_GetErrorPtr());
        return 1;
    }
    // 获取name字段,判断类型是否为字符串
    cJSON *name_obj = cJSON_GetObjectItem(root, "name");
    if (name_obj != NULL && name_obj->type == cJSON_String) {
        printf("用户名:%sn", name_obj->valuestring);
    }
    // 获取age字段,判断类型是否为数字
    cJSON *age_obj = cJSON_GetObjectItem(root, "age");
    if (age_obj != NULL && age_obj->type == cJSON_Number) {
        printf("年龄:%dn", age_obj->valueint);
    }
    // 释放cJSON对象内存
    cJSON_Delete(root);
    return 0;
}

解析复杂结构的json数据

实际场景中的json往往包含数组、嵌套对象等复杂结构,cJSON同样提供了对应的接口处理这类情况,比如获取数组大小、遍历数组元素、获取嵌套对象的字段等。

解析数组和嵌套对象示例

下面是一个包含嵌套对象和数组的json示例,解析其所有内容:

#include <stdio.h>
#include <stdlib.h>
#include "cJSON.h"

int main() {
    // 包含嵌套对象和数组的json字符串
    char *json_str = "{"user":{"name":"李四","age":30},"hobbies":["篮球","阅读","编程"],"is_student":false}";
    cJSON *root = cJSON_Parse(json_str);
    if (root == NULL) {
        printf("json解析失败n");
        return 1;
    }
    // 解析嵌套的user对象
    cJSON *user_obj = cJSON_GetObjectItem(root, "user");
    if (user_obj != NULL) {
        cJSON *name = cJSON_GetObjectItem(user_obj, "name");
        cJSON *age = cJSON_GetObjectItem(user_obj, "age");
        if (name != NULL && name->type == cJSON_String) {
            printf("用户姓名:%sn", name->valuestring);
        }
        if (age != NULL && age->type == cJSON_Number) {
            printf("用户年龄:%dn", age->valueint);
        }
    }
    // 解析hobbies数组
    cJSON *hobbies_arr = cJSON_GetObjectItem(root, "hobbies");
    if (hobbies_arr != NULL && hobbies_arr->type == cJSON_Array) {
        int arr_size = cJSON_GetArraySize(hobbies_arr);
        printf("爱好列表(共%d项):n", arr_size);
        for (int i = 0; i < arr_size; i++) {
            cJSON *item = cJSON_GetArrayItem(hobbies_arr, i);
            if (item != NULL && item->type == cJSON_String) {
                printf("  第%d项:%sn", i+1, item->valuestring);
            }
        }
    }
    // 解析布尔值字段
    cJSON *is_student = cJSON_GetObjectItem(root, "is_student");
    if (is_student != NULL && is_student->type == cJSON_False) {
        printf("是否为学生:否n");
    } else if (is_student != NULL && is_student->type == cJSON_True) {
        printf("是否为学生:是n");
    }
    cJSON_Delete(root);
    return 0;
}

解析过程中的注意事项

  • 每次调用cJSON_Parse得到cJSON对象后,都必须调用cJSON_Delete释放内存,否则会造成内存泄漏。
  • 获取字段前一定要先判断字段是否存在,以及字段的类型是否符合预期,避免访问空指针或者错误类型的数据导致程序崩溃。
  • 如果json字符串格式错误,cJSON_Parse会返回NULL,此时可以通过cJSON_GetErrorPtr获取错误发生的位置,方便排查问题。
  • cJSON默认支持UTF-8编码的json字符串,如果处理的json包含其他编码,需要先转换为UTF-8再进行解析。

常见问题解答

如果json字段不存在会怎么样

cJSON_GetObjectItem函数在字段不存在时会返回NULL,因此一定要先做非空判断再使用返回值,否则会出现段错误。

解析大文件json需要注意什么

cJSON是将整个json加载到内存中解析的,如果json文件非常大,可能会占用过多内存,这种场景下可以考虑使用流式解析的库,或者分块读取json内容处理。

使用cJSON解析json时,所有操作都是基于cJSON对象树进行的,理解对象树的结构可以帮助你更快速地掌握复杂json的解析逻辑。

简单封装解析函数示例

为了更方便地获取json中的字符串字段,可以封装一个简单的函数,减少重复的判断逻辑:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cJSON.h"

// 封装获取json字符串字段的函数,不存在或者类型错误返回默认字符串
char* get_json_string(cJSON *root, const char *key, const char *default_val) {
    if (root == NULL || key == NULL) {
        return (char*)default_val;
    }
    cJSON *item = cJSON_GetObjectItem(root, key);
    if (item != NULL && item->type == cJSON_String) {
        return item->valuestring;
    }
    return (char*)default_val;
}

int main() {
    char *json_str = "{"title":"c语言json解析教程","author":"技术开发者"}";
    cJSON *root = cJSON_Parse(json_str);
    if (root == NULL) {
        return 1;
    }
    char *title = get_json_string(root, "title", "默认标题");
    char *author = get_json_string(root, "author", "未知作者");
    printf("标题:%sn作者:%sn", title, author);
    cJSON_Delete(root);
    return 0;
}

c语言json解析cJSON数据结构字符串处理修改时间:2026-07-20 14:21:38

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。