【嵌入式项目应用】__cJSON基础介绍与代码测试

目录

前言

一、JSON是什么?

1. JSON 基本语法

2. JSON值(value)的类型

3. 逻辑值(true 或 false)

4. null

5. NUMBER 数字(整数或浮点数)

6. STRING 字符串(在双引号""中)

7. ARRAY 数组(在中括号[]中)

8. OBJECT 对象(在大括号{}中)

二、cJSON又是什么

三、cJSON的编程实例

1. 例子1

2. 例子2

(* ̄︶ ̄)创作不易!期待你们的 点赞、收藏和评论喔。


前言

C语言开发中,你使用过cJSON吗?

在介绍cJSON之前,我们先来认识一下JSON。。。

一、JSON是什么?

JSON(JavaScript Object Notation)是一种轻量级数据交换格式。JSON 使用 Javascript语法来描述数据对象,但是 JSON 仍然独立于语言和平台。

1. JSON 基本语法

  • 数据以key :value(名称/值) 的形式存在
  • 数据由逗号,分隔
  • 大括号{}保存对象
  • 中括号[]保存数组,数组可以包含多个对象

例如:

{ name : C Primer pluse, pages : 626 }

2. JSON值(value)的类型

/* cJSON Types: */
#define cJSON_False 0
#define cJSON_True 1
#define cJSON_NULL 2
#define cJSON_Number 3
#define cJSON_String 4
#define cJSON_Array 5
#define cJSON_Object 6

3. 逻辑值(true 或 false)

{"flag":true}

4. null

{"name":null}

5. NUMBER 数字(整数或浮点数)

{"pages":200, "price":35.00}

6. STRING 字符串(在双引号""中)

{"book":"C Primer pluse"}

7. ARRAY 数组(在中括号[]中)

[
    {"name":"C Primer pluse", "author":"Stephen Prata"},
    {"name":"C程序设计", "author":"谭浩强"},
    {"name":"C陷阱与缺陷", "author":"Andrew Koenig"}
]

8. OBJECT 对象(在大括号{}中)

{"name":"C Primer pluse", "author":"Stephen Prata"}

当然对象内部也可以是数组,比如:

{
    "books":[
        {"name":"C Primer pluse", "author":"Stephen Prata"},
        {"name":"C程序设计", "author":"谭浩强"},
        {"name":"C陷阱与缺陷", "author":"Andrew Koenig"}
      ]
}

对象 books 内部是一个数组,该数组又包含了三个对象。

二、cJSON又是什么

cJSON是一个基于C的JSON解析库,这个库非常简短,源码内容只包含:一个 cJSON.h头文件 和一个 cJSON.c源文件 ,支持JSON的解析和封装,需要调用时,只需要#include "cJSON.h"就可以使用了。

cJSON源文件开源项目地址:https://sourceforge.net/projects/cjson/icon-default.png?t=N7T8https://sourceforge.net/projects/cjson/

 

三、cJSON的编程实例

1. 例子1

先演示一个最简单的JSON数据,如何使用cJSON库来解析。

用于测试JSON数据,我们先用一个char型的字符串了保存,注意,由于JSON对象的key和value都需要使用引号(数值或逻辑型value除外),所以,

使用C语言的字符串来保存JSON数据,在遇到引号时,要加反斜杠来转义

解析JSON数据时,首先要调用 cJSON_Parse() 这个函数,将JSON数据解析为 cJSON型的对象


cJSON *srcJsonData = cJSON_Parse(jsonData);

然后就可以使用cJSON库中提供的各种函数来操作这个对象。比如 :


value = cJSON_GetObjectItem(srcJsonData,"name");

就是通过 cJSON_GetObjectItem() 来获取JSON数据中的一项数据,并通过指定key的方式来获取对应的value。

整个测试程序如下:

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

void main(void)
{
    char jsonData[] = "{\"name\":\"C Primer pluse\",\"pages\":626}";

    cJSON *srcJsonData = cJSON_Parse(jsonData);
    if(!srcJsonData)
    {
        printf("Error:%s\r\n",cJSON_GetErrorPtr());
    }
    else
    {
        /*获取Json数据的内容*/
        cJSON *value;
        value = cJSON_GetObjectItem(srcJsonData,"name");/*通过key来获取value*/ 
        if(value->type == cJSON_String)/*字符串型的value*/ 
        {
            printf("书名:%s\r\n",value->valuestring);
        }

        value = cJSON_GetObjectItem(srcJsonData,"pages");/*通过key来获取value*/ 
        if(value->type == cJSON_Number)/*数值型的value*/ 
        {
            printf("页数:%d\r\n",value->valueint);
        }

        cJSON_Delete(srcJsonData);
    }
}

运行结果:

书名:C Primer pluse
页数:626

--------------------------------
Process exited after 0.01452 seconds with return value 0
请按任意键继续. . .

2. 例子2

上面是一个最基本的测试程序,JSON数据也是直接通过C语言的字符串保存的。

实际的使用中,JSON数据的内容较为庞大,再使用C语言的字符串来保存,则会及其麻烦(想想那一堆反斜杠)。

所以,一般都是使用文件的形式来保存JSON数据

准备一个原始数据用于测试,如下面的data.txt:

{
    "class":"C语言书籍",
    "books":[{
        "name":"C Primer pluse",
        "author":"Stephen Prata",
        "publishing":"人民邮电出版社"
        },

        {
        "name":"C程序设计",
        "author":"谭浩强",
        "publishing":"清华大学出版社"
        },

        {
        "name":"C陷阱与缺陷",
        "author":"Andrew Koenig",
        "publishing":"人民邮电出版社"
        }]
}

先来分析下这个JSON数据的结构:

  • 最外面的大括号,表示这个一个JSON对象

  • 对象里面有2个数据,key1是class,key2是books

  • books的value又是一个中括号表示的数组

  • 数组内又包含了3个对象,每个对象有3个数据,key1是name,key2是author,key3是publishing

解析这种JSON文件,使用要使用 fopen() 来打开这个文件:

FILE *fp = fopen("data.txt", "r");

这里还要使用 fseek() 和 ftell() 来计算文件的大小,目的是用于后面的分配内存时指定大小。

然后使用 fread() 将文件内存读入内存中分配的buf中:

fread(buf, fileSize, sizeof(char), fp);

接着,还是使用 cJSON_Parse() 将JSON数据解析为 cJSON型的对象

cJSON *srcJsonData = cJSON_Parse(buf);

然后就可以使用cJSON库中提供的各种函数来操作这个对象了。

这次会用到 cJSON_GetObjectItem()cJSON_GetArrayItem()cJSON_GetArraySize()cJSON_Print() 等函数。

注意是使用完cJSON_Print()后,要使用 free() 来释放。

具体的测试程序如下:

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

void main(void)
{
    /*打开JSON文件*/ 
    FILE *fp = fopen("data.txt", "r");
    if(fp == NULL)
    {
        return;
    } 

    /*计算文件大小*/ 
    int fileSize;
    fseek(fp, 0, SEEK_END);/*先移到文件末尾*/ 
    fileSize = ftell(fp);/*计算文件的大小*/ 
    printf("fileSize: %d\r\n", fileSize);
    fseek(fp, 0, SEEK_SET);/*再移到文件开头*/ 

    /*根据文件大小分配内存,并读取文件到内存*/ 
    char *buf = (char *)malloc(fileSize * sizeof(char));
    memset(buf, 0, fileSize);
    int ret = fread(buf, fileSize, sizeof(char), fp);
    if(ret == -1)
    {
        fclose(fp);
        return;
    }
    printf("%s\r\n",buf);
    fclose(fp);

    /*把该字符串数据转成JSON数据*/ 
    cJSON *srcJsonData = cJSON_Parse(buf);
    free(buf);
    if(srcJsonData == NULL)
    {
        printf("err\r\n");
        return;
    }

    cJSON *value;
    /*根据key值(class)获取对应的value*/
    value = cJSON_GetObjectItem(srcJsonData, "class");
    if(value == NULL)
    {
        printf("GetObjectItem err\r\n");
        cJSON_Delete(srcJsonData);
        return;
    }

    /*把value转成字符串输出*/
    char *data = cJSON_Print(value);
    printf("class = %s\r\n",data);
    free(data);


    /*根据key值(books)获取对应的value*/
    value = cJSON_GetObjectItem(srcJsonData, "books");
    if(value == NULL)
    {
        printf("GetObjectItem err\r\n");
        cJSON_Delete(srcJsonData);
        return;
    }

    /*获取该数组对象的大小*/
    int len = cJSON_GetArraySize(value);
    printf("books data: len=%d\r\n",len);

    /*访问books中的每一项*/ 
    int i = 0;
    for(i=0; i<len; i++)
    {
        /*先获取每一条信息*/
        cJSON *tmpValue = cJSON_GetArrayItem(value,i);

        /*再获取每条信息中的具体内容*/ 
        cJSON *nameValue = cJSON_GetObjectItem(tmpValue,"name");
        cJSON *authorValue = cJSON_GetObjectItem(tmpValue,"author");
        cJSON *publishValue = cJSON_GetObjectItem(tmpValue,"publishing");

        if(nameValue == NULL || authorValue == NULL || publishValue == NULL)
        {
            printf("GetObjectItem err\r\n");
            cJSON_Delete(srcJsonData);
            return;
        }

        /*打印出来*/ 
        char *print1 = cJSON_Print(nameValue);
        char *print2 = cJSON_Print(authorValue);
        char *print3 = cJSON_Print(publishValue);
        printf("[%d] %s \t %s \t %s\r\n",i+1,print1,print2,print3);
        free(print1);
        free(print2);
        free(print3);
    }
    cJSON_Delete(srcJsonData);
}

运行结果

fileSize: 433
{
   "class":"C语言书籍",
   "books":[{
       "name":"C Primer pluse",
       "author":"Stephen Prata",
       "publishing":"人民邮电出版社"
      },

      {
       "name":"C程序设计",
       "author":"谭浩强",
       "publishing":"清华大学出版社"
      },

      {
       "name":"C陷阱与缺陷",
       "author":"Andrew Koenig",
       "publishing":"人民邮电出版社"
      }]
}
class = "C语言书籍"
books data: len=3
[1] "C Primer pluse"     "Stephen Prata"         "人民邮电出版社"
[2] "C程序设计"          "谭浩强"        "清华大学出版社"
[3] "C陷阱与缺陷"        "Andrew Koenig"         "人民邮电出版社"

--------------------------------
Process exited after 0.01578 seconds with return value 0
请按任意键继续. . .


(* ̄︶ ̄)创作不易!期待你们的 点赞收藏评论喔。

本文来源网络,免费分享知识,版权归原作者所有。如涉及作品版权问题,请联系我进行删除!  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/112941.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

在NestJS应用程序中使用 Unleash 实现功能切换的指南

前言 近年来&#xff0c;软件开发行业迅速发展&#xff0c;功能开关&#xff08;Feature Toggle&#xff09;成为了一种常见的开发实践。通过功能开关&#xff0c;可以在运行时动态地启用或禁用应用程序的特定功能&#xff0c;以提供更灵活的软件交付和配置管理。对于使用 Nes…

手把手教你使用Vue2.0实现动态路由展示

文章目录 VUE2相关组件版本原始菜单数据数据库数据树形数据 前端项目配置静态路由配置路由守卫左侧路由回显代码 使用Vue2实现动态路由展示 思路&#xff1a; 后端返回树形数据根据数据渲染左侧菜单根据数据组装路由数据 注意&#xff1a;本文主要目的讲解是一种思路&#xff0…

阿里云推出AI编程工具“通义灵码“;生成式 AI 入门教程 2

&#x1f989; AI新闻 &#x1f680; 阿里云推出AI编程工具"通义灵码"&#xff0c;支持多种语言及实时续写功能 摘要&#xff1a;阿里云推出了一款名为"通义灵码"的AI编程工具&#xff0c;支持多种主流编程语言&#xff0c;包括Java、Python、Go等。该工…

找到数组中出现一种/两种奇数——异或运算

找到数组中出现一种/两种奇数 题目&#xff1a;一个数组有一种数出现了奇数次&#xff0c;其他数都出现了偶数次&#xff0c;怎么找到并打印这个数&#xff1f; trick 因为异或运算有个特点&#xff0c;满足交换律和结合律&#xff0c;同时有两个重要的特点&#xff1a; n^n…

Xray+awvs联动扫描

首先xray开启监听 xray_windows_amd64.exe webscan --listen 127.0.0.1:7777 --html-output xray-xxx.html --plugins sqldet,xxe,upload,brute-force,cmd-injection,struts,thinkphp 然后准备目标csv文件,每行一个url或ip然后加个逗号 接着awvs导入csv 对导进来的每个目…

沉痛悼念科研分公司

今天上班途中&#xff0c;遇到了上家公司的同事王强。他正准备去体检中心体检。几句寒暄之后&#xff0c;得知他是要入职选煤公司了。 我们所在的公司比较大&#xff0c;总公司下设有几十个分、子公司&#xff0c;我和他曾经在一家子公司——科研分公司。现在的科研分公司解散…

FIFO 位宽转换

从8位转32位 module tb_fifo();reg clk,rst; initial beginclk0;forever #4.545 clk~clk; end initial beginrst1;#9.09 rst0; endreg [31:0] cnts; always (posedge clk or posedge rst) beginif(rst)begincnts < 32d0;endelsebegincnts < cnts 1b1;end endreg […

中国电子云-隐私计算-云原生安全可信计算,物理-硬件-系统-云产品-云平台,数据安全防护

目录 联邦学习的架构思想 中国电子云-隐私计算-云原生安全 可信计算&#xff0c;物理-硬件-系统-云产品-云平台&#xff0c;数据安全防护 全栈国产信创的意义 1. 提升科技创新能力 2. 推动经济发展 3. 加强信息安全与自主可控 全栈国产信创的重要领域 1. 人工智能 2.…

硬件加速器及其深度神经网络模型的性能指标理解

前言&#xff1a; 现如今&#xff0c;深度神经网络模型和硬件加速器&#xff0c;如GPU、TPU等的关系可谓是“不分彼此”&#xff0c;随着模型参数的增加&#xff0c;硬件加速器成为了训练、推理深度神经网络不可或缺的一个工具&#xff0c;而近年来硬件加速器的发展也得益于加速…

AlphaFold更新了!AlphaFold-latest

AlphaFold又有重大更新了&#xff01;AlphaFold-latest来了&#xff01; &#x1f508;&#xff1a;号外号外&#xff01;Google DeepMind联合Isomorphic Labs在2023年10月31日发布了新一代的AlphaFold&#xff08;AlphaFold-latest&#xff09;。 AlphaFold-latest显着提高了…

论文阅读 - Detecting Social Bot on the Fly using Contrastive Learning

目录 摘要&#xff1a; 引言 3 问题定义 4 CBD 4.1 框架概述 4.2 Model Learning 4.2.1 通过 GCL 进行模型预训练 4.2.2 通过一致性损失进行模型微调 4.3 在线检测 5 实验 5.1 实验设置 5.2 性能比较 5.5 少量检测研究 6 结论 https://dl.acm.org/doi/pdf/10.1145/358…

Qt信号槽

目录 1、信号的定义 2、槽定义 3、信号和槽连接 4、信号与槽断开连接 5、伪代码展示 6、注意 Qt中的信号&#xff08;signals&#xff09;和槽&#xff08;slots&#xff09;是一种用于实现对象间通信的机制&#xff0c;广泛用于Qt应用程序中&#xff0c;特别是在图形用户…

【华为】路由器以PPPoE拨号接入广域网

组网需求 用户希望以PPPoE拨号方式接入广域网&#xff0c;如图1所示&#xff0c;Router作为PPPoE客户端&#xff0c;得到PPPoE服务器的认证后获得IP地址&#xff0c;实现用户接入互联网的需求。内网网关地址&#xff08;即VLANIF1接口的IP地址&#xff09;为10.137.32.1/24。 …

资源限流 + 本地分布式多重锁——高并发性能挡板,隔绝无效流量请求

前言 在高并发分布式下&#xff0c;我们往往采用分布式锁去维护一个同步互斥的业务需求&#xff0c;但是大家细想一下&#xff0c;在一些高TPS的业务场景下&#xff0c;让这些请求全部卡在获取分布式锁&#xff0c;这会造成什么问题&#xff1f; 瞬时高并发压垮系统 众所周知…

Go Metrics SDK Tag 校验性能优化实践

背景 Metrics SDK 是与字节内场时序数据库 ByteTSD 配套的用户指标打点 SDK&#xff0c;在字节内数十万服务中集成&#xff0c;应用广泛&#xff0c;因此 SDK 的性能优化是个重要和持续性的话题。本文主要以 Go Metrics SDK 为例&#xff0c;讲述对打点 API 的 hot-path 优化的…

当函数参数为一级指针,二级指针

当函数参数为一级指针&#xff0c;二级指针 在讲述内容之前&#xff0c;先讲四点重要知识 1.当传入参数时&#xff0c;函数形参会立即申请形参的内存空间&#xff0c;函数执行完毕后&#xff0c;形参的内存空间立即释放掉。 1.指针是存放其他变量地址的变量。指针有自己的内…

ECharts折线图去掉图例和线段上的小圆点

官方的初始效果 折线图的图例有小圆点&#xff0c;并且图表中也有小圆点 最终效果 去掉图例和图标中的小圆点 并且柱状图和折线图的图例要不同 代码实现 去掉图例小圆点 官方文档 itemStyle: { opacity: 0 } 折线图中的小圆点去掉 官方文档 两个代码二选一就行&#x…

设计模式04———桥接模式 c#

桥接模式&#xff1a;将一个事物从多个维度抽象出来&#xff0c;采用 分离 和 组合 的方式 替代 原本类的继承 桥接模式&#xff08;Bridge Pattern&#xff09;是一种软件设计模式&#xff0c;属于结构型模式&#xff0c;它用于将抽象部分与具体实现部分分离&#xff0c;以便它…

Jorani远程命令执行漏洞 CVE-2023-26469

Jorani远程命令执行漏洞 CVE-2023-26469 漏洞描述漏洞影响漏洞危害网络测绘Fofa: title"Jorani"Hunter: web.title"Jorani" 漏洞复现1. 获取cookie2. 构造poc3. 执行命令 漏洞描述 Jorani是一款开源的员工考勤和休假管理系统&#xff0c;适用于中小型企业…

EASYX实现多物体运动

eg1:单个物体运动使用easyx实现单个小球的运动 #include <stdio.h> #include <easyx.h> #include <iostream> #include <math.h> #include <stdlib.h> #include <conio.h> #include <time.h> #define PI 3.14 #define NODE_WIDTH 4…