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

news2024/11/26 2:56:44

目录

前言

一、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
请按任意键继续. . .


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

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ChatGLM3-6B详细安装过程记录(Linux)

先附上GitHub官方地址: https://github.com/THUDM/ChatGLM3https://github.com/THUDM/ChatGLM3 一、预览 咱们可以先看看完成之后的界面: 1. 基于 Gradio 的网页版 demo 运行以下命令即可打开界面: python web_demo.py 运行界面如下: 2. 基于 Streamlit 的网页版 de…

【23真题】难!均79分!211题目强过985!

今天分享的是23年海南大学838的信号与系统试题及解析。 本套试卷难度分析&#xff1a;22年海南大学838考研真题&#xff0c;我也做过&#xff0c;若有需要戳这里自取&#xff01;平均分为80-90左右&#xff0c;最高分为133分。本套试题难度中等偏上&#xff0c;题量不多&#…

Python画图之草莓熊

Python-turtle画出草莓熊&#xff08;有趣小游戏&#xff09; 一、效果图二、Python代码 一、效果图 二、Python代码 # -*- coding: UTF-8 -*- import turtle as t# 设置背景颜色&#xff0c;窗口位置以及大小 t.colormode(255) # 颜色模式 t.speed(0) t.screensize(850, 760…

通过Python脚本支持OC代码重构实践(二):数据项提供模块接入数据通路的代码生成

作者 | 刘俊启 导读 在软件开发中&#xff0c;经常会遇到一些代码问题&#xff0c;例如逻辑结构复杂、依赖关系混乱、代码冗余、不易读懂的命名等。这些问题可能导致代码的可维护性下降&#xff0c;增加维护成本&#xff0c;同时也会影响到开发效率。这时通常通过重构的方式对已…

STM32智能小车(循迹、跟随、避障、测速、蓝牙、wife、4g、语音识别)总结

目录 1.电机模块开发 1.1 让小车动起来 1.2 串口控制小车方向 1.3 如何进行小车PWM调速 1.4 PWM方式实现小车转向 2.循迹小车 2.1 循迹模块使用 2.2 循迹小车原理 2.3 循迹小车核心代码 2.4 循迹小车解决转弯平滑问题 3.跟随/避障小车 3.1 红外壁障模块分析​编辑 …

Redis 应用问题

1-缓存穿透 1.1-问题描述 Key 对应的数据在数据源并不存在&#xff0c;每次针对此 Key 的请求从缓存获取不到&#xff0c;请求都会压到数据源&#xff0c;从而可能压垮数据源。 比如&#xff1a;用一个不存在的用户ID 获取用户信息&#xff0c;不论缓存还是数据库都没有&…

有哪些适合做小说推文的配音软件?

其实现在市面上的短视频配音软件数不胜数&#xff0c;怎样才能挑选到简单又实用的呢&#xff1f;今天我就来给你盘一盘各大配音软件的优缺点&#xff0c;大家可以根据自己的需求来选择合适的配音软件&#xff01; 一、悦音配音 推荐指数★★★★★ 推荐理由&#xff1a;无需自…

SpringBoot SerializationUtils克隆(反序列化) 类加载器不一致问题(ClassCastException)

问题分析 在SpringBoot中使用 org.apache.commons.lang.SerializationUtils.clone 方法时&#xff0c;发现克隆出来的类强转对应类时发生类型不一致的错误&#xff0c;经过检测发现两个看似相同的类的类加载器不一致 场景 报错信息 java.lang.ClassCastException: com.tianq…

伦敦金投资怎么玩收益高?

伦敦金&#xff0c;作为国际黄金市场的代表&#xff0c;一直备受投资者的关注。它有着高流动性和丰富的投资机会&#xff0c;但要真正玩得收益高&#xff0c;就需要掌握一些关键的方法和技巧。在本文中&#xff0c;万洲金业将为您提供专业建议&#xff0c;告诉您伦敦金投资怎么…

【广州华锐互动】VR虚拟现实技术在森林防火教学中的应用

在探索大自然的神秘面纱时&#xff0c;我们往往会遇到一些意想不到的风险&#xff0c;其中之一就是森林火灾。森林火灾是一种毁灭性的自然灾害&#xff0c;可以在短时间内摧毁大片森林&#xff0c;对人类和动物的生存环境造成严重影响。然而&#xff0c;通过3D仿真技术&#xf…

SteerMouse for mac Mac万能鼠标设置工具 功能介绍

鼠标可谓是用户们在使用电脑时候的必备外接设备呢&#xff01;适合你自己的鼠标设置也绝对能够优化你的Mac使用体验&#xff01;想要更好的Mac体验就试试用Steermouse Mac版吧。它通过软件来自由设置你的鼠标操作&#xff01;在这款万能鼠标设置工具中&#xff0c;用户可以在偏…

uniapp在APP端使用swiper进行页面不卡顿滑动

uniapp在APP端使用swiper进行页面会卡顿&#xff0c;主要是渲染的数据有点多&#xff0c;这里只渲染三个数据就不好那么卡顿了&#xff0c;每次滑动后更新数据 <view><swiper change"changePoint" circular :disable-touch"disableTouch"><…

【Excel密码】四个方法,设置excel表格只读模式

Excel文件想要设置成只读模式&#xff0c;其实很简单&#xff0c;今天给大家分享四个excel设置只读模式的方法。 方法一&#xff1a;文件属性 右键点击文件&#xff0c;查看文件属性&#xff0c;在属性界面&#xff0c;勾选上只读属性就可以了。 方法二&#xff1a;始终以只读…

g.Grafana之Gauge的图形说明

直接上操作截图 1. 创建一个新的Dashboard 2.为Dashboard创建变量 【General】下的Name与Label的名称自定义 【Query options】 下的Group可以填写Zabbix内的所有组/.*/ , 然后通过Regex正则过滤需要的组名 3.设置Dashboard的图形 我使用文字来描述下这个图 1.我们在dash…

【分享】winterm ssh登录报错Unkown error

非软文哈&#xff0c;实测Winterm非常好用&#xff0c;唯一的障碍是 某些特定服务器ssh登录报错Unkown error 后经github issue得知&#xff0c;关闭会话设置-ssh选项卡中的 尝试键盘交互认证的勾即可。 https://github.com/kingToolbox/WindTerm/issues/1922

【C++】基础语法(上)

C基础语法 此语法笔记面向算法竞赛考研&#xff0c;可供参考&#xff0c;本人的一些笔记的记录~ 失踪人口回归&#xff0c;将近半个月没有更新&#xff0c;那么接下来也会逐步开始更新分享知识内容~ 本篇将分享cpp基础语法中的变量、输出输入语句、表达式、顺序语句、条件判断…

el-table添加class类名并添加样式

先上效果图&#xff1a;输入框内容被 内边距 padding: 0 12px; 但是只想在这列开始去除内边距 理想效果 解决方案 AddClass <!-- 给某个td里面添加类名:cell-class-name --> <el-table:data"data"size"mini"borderselection-change"sele…