松垮垮 松垮垮
首页
  • GPU并行编程
  • 图形学
  • 归并算法
  • 计算机视觉
  • css
  • html
  • JavaScript
  • vue
  • 压缩命令
  • cmdline
  • Docker
  • ftrace跟踪技术
  • gcov代码覆盖率测试
  • GDB
  • git
  • kgdb
  • linux操作
  • markdown
  • systemtap
  • valgrind
  • 设计模式
  • 分布式
  • 操作系统
  • 数据库
  • 服务器
  • 网络
  • C++
  • c语言
  • go
  • JSON
  • Makefile
  • matlab
  • OpenGL
  • python
  • shell
  • 正则表达式
  • 汇编
  • GPU并行编程
  • mysql
  • nginx
  • redis
  • 网络
  • 计算机视觉
  • 进程管理
  • linux调试
  • 【Python】:re.error bad escape i at position 4
  • 搭建ai知识助手
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

松垮垮

c++后端开发工程师
首页
  • GPU并行编程
  • 图形学
  • 归并算法
  • 计算机视觉
  • css
  • html
  • JavaScript
  • vue
  • 压缩命令
  • cmdline
  • Docker
  • ftrace跟踪技术
  • gcov代码覆盖率测试
  • GDB
  • git
  • kgdb
  • linux操作
  • markdown
  • systemtap
  • valgrind
  • 设计模式
  • 分布式
  • 操作系统
  • 数据库
  • 服务器
  • 网络
  • C++
  • c语言
  • go
  • JSON
  • Makefile
  • matlab
  • OpenGL
  • python
  • shell
  • 正则表达式
  • 汇编
  • GPU并行编程
  • mysql
  • nginx
  • redis
  • 网络
  • 计算机视觉
  • 进程管理
  • linux调试
  • 【Python】:re.error bad escape i at position 4
  • 搭建ai知识助手
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • C++

    • C++11
    • C++17
    • c++规范
    • cmake和宏开关
    • 为了高效
    • 作用域和生命周期
    • 关键字
    • 内存分配
    • 基础
    • 容器
    • 对象和类
    • 线程
  • c语言
  • Go

  • JSON
    • 数据创建API
    • 数据解析API
    • 内存问题
    • 数据替换
  • Makefile
  • matlab

  • OpenGL
  • python

  • shell
  • 正则表达式
  • 汇编
  • 语言
songkuakua
2025-02-15
目录

JSON

# JSON

Owner: -QVQ-

# JSON

JavaScript Object Notation,一种轻量级的数据格式

JSON对象是一个无序的"名称/值"键值对的集合:

  • 以"{“开始,以”}"结束,允许嵌套使用;
  • 每个名称和值成对出现,名称和值之间使用":"分隔;
  • 键值对之间用","分隔
  • 在这些字符前后允许存在无意义的空白符;

对于键值,可以有如下值:

  • 一个新的json对象
  • 数组:使用"[“和”]"表示
  • 数字:直接表示,可以是整数,也可以是浮点数
  • 字符串:使用引号"表示
  • 字面值:false、null、true中的一个(必须是小写)
{
    "name": "mculover666",
    "age": 22,
    "weight": 55.5,
    "address":
    {
        "country": "China",
        "zip-code": 111111
    },
    "skill": ["c", "Java", "Python"],
    "student": false
}
1
2
3
4
5
6
7
8
9
10
11
12

# cJSON

C语言编写的JSON数据解析器

git clone [https://github.com/DaveGamble/cJSON.git](https://github.com/DaveGamble/cJSON.git)

其中的源文件只有两个:

  • cJSON.h
  • cJSON.c

其使用cJSON结构体来表示一个JSON数据

  • struct cJSON

    /* The cJSON structure: */
    typedef struct cJSON
    {
        struct cJSON *next;//指向下一个键值对
        struct cJSON *prev;//指向上一个键值对
    
        struct cJSON *child;//指向下一个嵌套的键值对,或者一个数组
    
        int type;//表示该键值对的名称
    
        char *valuestring;//如果键值类型(type)是字符串,则将该指针指向键值
    
        int valueint;//如果键值类型(type)是整数,则将该指针指向键值
        
        double valuedouble;//如果键值类型(type)是浮点数,则将该指针指向键值;
    
        char *string;//表示该键值对的名称
    } cJSON;
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

# 数据创建API

  • char* cJSON_Print(const cJSON *item);

将链表的内容输出到一个字符串中

  • cJSON_CreateObject()

创建一个JSON数据对象(链表头结点)

  • cJSON_AddStringToObject(cJSON*, char*, char*)

添加一条字符串数据,

第一个参数是添加对象

第二个参数是参数名字

第三个参数是添加内容

  • cJSON_AddNumberToObject(cJSON*, char*, int)

添加一个数值数据,可以是int或者float数据

第一个参数是添加对象

第二个参数是参数名字

第三个参数是添加内容

  • cJSON_AddItemToObject(cJSON* c1, char*, cJSON* c2)

添加一个cJSON内容,向c1添加c2,第二个参数是名字

  • cJSON_CreateArray()

创建一个数组对象

  • cJSON_CreateString(char*)

将char*类型转换为一个cJSON对象

  • cJSON_AddItemToArray(cJSON *array, cJSON *item)

添加item数组内容入array,直接没有办法插入,必须调用上面的转换函数

  • cJSON_AddFalseToObject(cJSON *object, const char *string)

添加一个bool数据,false或true

  • 对于上面哪个JSON数据的封装操作

    #include <stdio.h>
    #include "cJSON.h"
    
    int main(void)
    {
        cJSON* cjson_test = NULL;
        cJSON* cjson_address = NULL;
        cJSON* cjson_skill = NULL;
        char* str = NULL;
    
        /* 创建一个JSON数据对象(链表头结点) */
        cjson_test = cJSON_CreateObject();
    
        /* 添加一条字符串类型的JSON数据(添加一个链表节点) */
        cJSON_AddStringToObject(cjson_test, "name", "mculover666");
    
        /* 添加一条整数类型的JSON数据(添加一个链表节点) */
        cJSON_AddNumberToObject(cjson_test, "age", 22);
    
        /* 添加一条浮点类型的JSON数据(添加一个链表节点) */
        cJSON_AddNumberToObject(cjson_test, "weight", 55.5);
    
        /* 添加一个嵌套的JSON数据(添加一个链表节点) */
        cjson_address = cJSON_CreateObject();
        cJSON_AddStringToObject(cjson_address, "country", "China");
        cJSON_AddNumberToObject(cjson_address, "zip-code", 111111);
        cJSON_AddItemToObject(cjson_test, "address", cjson_address);
    
        /* 添加一个数组类型的JSON数据(添加一个链表节点) */
        cjson_skill = cJSON_CreateArray();
        cJSON_AddItemToArray(cjson_skill, cJSON_CreateString( "C" ));
        cJSON_AddItemToArray(cjson_skill, cJSON_CreateString( "Java" ));
        cJSON_AddItemToArray(cjson_skill, cJSON_CreateString( "Python" ));
        cJSON_AddItemToObject(cjson_test, "skill", cjson_skill);
    
        /* 添加一个值为 False 的布尔类型的JSON数据(添加一个链表节点) */
        cJSON_AddFalseToObject(cjson_test, "student");
    
        /* 打印JSON对象(整条链表)的所有数据 */
        str = cJSON_Print(cjson_test);
        printf("%s\n", str);
    
        return 0;
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44

# 数据解析API

cJSON * cJSON_Parse(const char *value);

将一个符合json数据结构的字符串转换为cJSON结构体。,返回链表头节点指针

cJSON * cJSON_GetObjectItem(const cJSON * const object, const char * const string);

根据键值对的名称从链表中取出对应的值,返回该键值对(链表节点)的地址

一个函数可以读取所有类型的

int cJSON_GetArraySize(const cJSON *array);

返回数组类型数据的大小

cJSON * cJSON_GetArrayItem(const cJSON *array, int index);

返回数组类型的cJSON

  • 例子

    #include <stdio.h>
    #include "cJSON.h"
    
    char *message = 
    "{                              \
        \"name\":\"mculover666\",   \
        \"age\": 22,                \
        \"weight\": 55.5,           \
        \"address\":                \
            {                       \
                \"country\": \"China\",\
                \"zip-code\": 111111\
            },                      \
        \"skill\": [\"c\", \"Java\", \"Python\"],\
        \"student\": false          \
    }";
    
    int main(void)
    {
        cJSON* cjson_test = NULL;
        cJSON* cjson_name = NULL;
        cJSON* cjson_age = NULL;
        cJSON* cjson_weight = NULL;
        cJSON* cjson_address = NULL;
        cJSON* cjson_address_country = NULL;
        cJSON* cjson_address_zipcode = NULL;
        cJSON* cjson_skill = NULL;
        cJSON* cjson_student = NULL;
        int    skill_array_size = 0, i = 0;
        cJSON* cjson_skill_item = NULL;
    
        /* 解析整段JSO数据 */
        cjson_test = cJSON_Parse(message);
        if(cjson_test == NULL)
        {
            printf("parse fail.\n");
            return -1;
        }
    
        /* 依次根据名称提取JSON数据(键值对) */
        cjson_name = cJSON_GetObjectItem(cjson_test, "name");
        cjson_age = cJSON_GetObjectItem(cjson_test, "age");
        cjson_weight = cJSON_GetObjectItem(cjson_test, "weight");
    
        printf("name: %s\n", cjson_name->valuestring);
        printf("age:%d\n", cjson_age->valueint);
        printf("weight:%.1f\n", cjson_weight->valuedouble);
    
        /* 解析嵌套json数据 */
        cjson_address = cJSON_GetObjectItem(cjson_test, "address");
        cjson_address_country = cJSON_GetObjectItem(cjson_address, "country");
        cjson_address_zipcode = cJSON_GetObjectItem(cjson_address, "zip-code");
        printf("address-country:%s\naddress-zipcode:%d\n", cjson_address_country->valuestring, cjson_address_zipcode->valueint);
    
        /* 解析数组 */
        cjson_skill = cJSON_GetObjectItem(cjson_test, "skill");
        skill_array_size = cJSON_GetArraySize(cjson_skill);
        printf("skill:[");
        for(i = 0; i < skill_array_size; i++)
        {
            cjson_skill_item = cJSON_GetArrayItem(cjson_skill, i);
            printf("%s,", cjson_skill_item->valuestring);
        }
        printf("\b]\n");
    		//若要将json的数据写入文件需要先用cJSON_PrintUnformatted转为字符串,再写入
        /* 解析布尔型数据 */
        cjson_student = cJSON_GetObjectItem(cjson_test, "student");
        if(cjson_student->valueint == 0)
        {
            printf("student: false\n");
        }
        else
        {
            printf("student:error\n");
        }
        
        return 0;
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78

在实际使用时,如果提前不确定数据类型,应该先判断type的值,确定数据类型,再从对应的数据域中提取数据

char * cJSON_Print(const cJSON *item);

char* cJSON_PrintUnformatted(cJSON *)

将cJSON数据解析成JSON字符串,并在堆中开辟一块char*的内存空间存储JSON字符串。cJSON_PrintUnformatted()与cJSON_Print()类似,只是打印输出不带格式,而只是一个字符串数据

# 内存问题

void cJSON_Delete(cJSON *item);

内存释放函数,如果有嵌套会连带删除

钩子函数

CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);

typedef struct cJSON_Hooks
{
      void *(CJSON_CDECL *malloc_fn)(size_t sz);
      void (CJSON_CDECL *free_fn)(void *ptr);
} cJSON_Hooks;
1
2
3
4
5

CJSON_PUBLIC(void *) cJSON_malloc(size_t size); CJSON_PUBLIC(void) cJSON_free(void *object);

# 数据替换

cJSON_ReplaceItemInObjectCaseSensitive(旧的json,char* key,新的json)函数的功能是将JSON对象中指定名称的键值对替换为新的键值对。指定的名称字符串是区分大小写的。新的键值对是由一个cJSON指针提供的。函数返回一个指向替换后的对象的指针,如果对象或字符串为NULL,则返回NULL。

# yyjson

高性能json库

上次更新: 2025/02/21, 14:57:10
进阶
Makefile

← 进阶 Makefile→

最近更新
01
搭建ai知识助手
02-23
02
边缘检测
02-15
03
css
02-15
更多文章>
Theme by Vdoing | Copyright © 2025-2025 松垮垮 | MIT License | 蜀ICP备2025120453号 | 川公网安备51011202000997号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 纯净模式