C/C++程序开发: cJSON的使用(创建与解析JSON数据)

简介: C/C++程序开发: cJSON的使用(创建与解析JSON数据)

一、cJSON介绍

     cJSON 是一个超轻巧,携带方便,单文件,可以作为 ANSI-C 标准的 JSON 解析器,是一个用C语言编写的简单好用的JSON解析器;它只包含一个C文件和一个头文件,可以非常容易集成到自己工程项目中。


       并且cJSON是用ANSI C(C89)编写的,可以兼容所有支持C语言的平台和编译器。


       cJSON下载地址:  

cJSON download | SourceForge.net

https://sourceforge.net/projects/cjson/


      cJSON的GitHub仓库地址:

https://github.com/DaveGamble/cJSON

https://github.com/DaveGamble/cJSON

image.png

二、JSON简介、语法介绍

2.1 JSON是什么?

   JSON是JavaScript Object Notation(JavaScript对象表示法),是一种轻量级的数据交换格式。    


   JSON主要是用来存储和交换文本信息,类似XML格式;但是JSON比XML更小、更快,更易解析。


   JSON是基于ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。


      简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。 比如: Web服务器接口基本都是采用JSON反馈数据,采用JSON格式字符串来描述符信息。 JSON文件的后缀一般是.json,这个只是为了方便辨识。


  简单的说,JSON就是按照指定格式序列化的字符串,就算不使用任何现成的解析库,自己也可以按照正常解析字符串的思路去解析;有现成的标准JSON解析库,那就大大减轻了我们的工作量。  


  JSON格式的数据示例:  这是表示当前时间的JSON字符串

{
  "success": "1",
  "result": {
    "timestamp": "1631849514",
    "datetime_1": "2021-09-17 20:31:54",
    "datetime_2": "2021年09月17日 20时31分54秒",
    "week_1": "5",
    "week_2": "星期五",
    "week_3": "周五",
    "week_4": "Friday"
  }
}

  JSON格式的数据示例:  这是表示未来几天天气预报的json字符串

{
  "success": "1",
  "result": [
    {
      "weaid": "1",
      "days": "2021-09-17",
      "week": "星期五",
      "cityno": "beijing",
      "citynm": "北京",
      "cityid": "101010100",
      "temperature": "26℃/17℃",
      "humidity": "0%/0%",
      "weather": "晴",
      "weather_icon": "http://api.k780.com/upload/weather/d/0.gif",
      "weather_icon1": "http://api.k780.com/upload/weather/n/0.gif",
      "wind": "北风转西南风",
      "winp": "小于3级",
      "temp_high": "26",
      "temp_low": "17",
      "humi_high": "0",
      "humi_low": "0",
      "weatid": "1",
      "weatid1": "1",
      "windid": "8",
      "winpid": "0",
      "weather_iconid": "0",
      "weather_iconid1": "0"
    },
    {
      "weaid": "1",
      "days": "2021-09-18",
      "week": "星期六",
      "cityno": "beijing",
      "citynm": "北京",
      "cityid": "101010100",
      "temperature": "25℃/17℃",
      "humidity": "0%/0%",
      "weather": "多云",
      "weather_icon": "http://api.k780.com/upload/weather/d/1.gif",
      "weather_icon1": "http://api.k780.com/upload/weather/n/1.gif",
      "wind": "西南风",
      "winp": "小于3级",
      "temp_high": "25",
      "temp_low": "17",
      "humi_high": "0",
      "humi_low": "0",
      "weatid": "2",
      "weatid1": "2",
      "windid": "5",
      "winpid": "0",
      "weather_iconid": "1",
      "weather_iconid1": "1"
    },
    {
      "weaid": "1",
      "days": "2021-09-19",
      "week": "星期日",
      "cityno": "beijing",
      "citynm": "北京",
      "cityid": "101010100",
      "temperature": "19℃/15℃",
      "humidity": "0%/0%",
      "weather": "小雨转中雨",
      "weather_icon": "http://api.k780.com/upload/weather/d/7.gif",
      "weather_icon1": "http://api.k780.com/upload/weather/n/8.gif",
      "wind": "西南风转北风",
      "winp": "小于3级转小于3级",
      "temp_high": "19",
      "temp_low": "15",
      "humi_high": "0",
      "humi_low": "0",
      "weatid": "8",
      "weatid1": "9",
      "windid": "5",
      "winpid": "0",
      "weather_iconid": "7",
      "weather_iconid1": "8"
    },
    {
      "weaid": "1",
      "days": "2021-09-20",
      "week": "星期一",
      "cityno": "beijing",
      "citynm": "北京",
      "cityid": "101010100",
      "temperature": "26℃/16℃",
      "humidity": "0%/0%",
      "weather": "多云转晴",
      "weather_icon": "http://api.k780.com/upload/weather/d/1.gif",
      "weather_icon1": "http://api.k780.com/upload/weather/n/0.gif",
      "wind": "北风",
      "winp": "3-4级转3-4级",
      "temp_high": "26",
      "temp_low": "16",
      "humi_high": "0",
      "humi_low": "0",
      "weatid": "2",
      "weatid1": "1",
      "windid": "8",
      "winpid": "1",
      "weather_iconid": "1",
      "weather_iconid1": "0"
    },
    {
      "weaid": "1",
      "days": "2021-09-21",
      "week": "星期二",
      "cityno": "beijing",
      "citynm": "北京",
      "cityid": "101010100",
      "temperature": "27℃/16℃",
      "humidity": "0%/0%",
      "weather": "晴",
      "weather_icon": "http://api.k780.com/upload/weather/d/0.gif",
      "weather_icon1": "http://api.k780.com/upload/weather/n/0.gif",
      "wind": "西北风转北风",
      "winp": "小于3级",
      "temp_high": "27",
      "temp_low": "16",
      "humi_high": "0",
      "humi_low": "0",
      "weatid": "1",
      "weatid1": "1",
      "windid": "7",
      "winpid": "0",
      "weather_iconid": "0",
      "weather_iconid1": "0"
    },
    {
      "weaid": "1",
      "days": "2021-09-22",
      "week": "星期三",
      "cityno": "beijing",
      "citynm": "北京",
      "cityid": "101010100",
      "temperature": "26℃/18℃",
      "humidity": "0%/0%",
      "weather": "多云",
      "weather_icon": "http://api.k780.com/upload/weather/d/1.gif",
      "weather_icon1": "http://api.k780.com/upload/weather/n/1.gif",
      "wind": "北风转东北风",
      "winp": "小于3级",
      "temp_high": "26",
      "temp_low": "18",
      "humi_high": "0",
      "humi_low": "0",
      "weatid": "2",
      "weatid1": "2",
      "windid": "8",
      "winpid": "0",
      "weather_iconid": "1",
      "weather_iconid1": "1"
    },
    {
      "weaid": "1",
      "days": "2021-09-23",
      "week": "星期四",
      "cityno": "beijing",
      "citynm": "北京",
      "cityid": "101010100",
      "temperature": "24℃/16℃",
      "humidity": "0%/0%",
      "weather": "多云",
      "weather_icon": "http://api.k780.com/upload/weather/d/1.gif",
      "weather_icon1": "http://api.k780.com/upload/weather/n/1.gif",
      "wind": "东北风",
      "winp": "小于3级",
      "temp_high": "24",
      "temp_low": "16",
      "humi_high": "0",
      "humi_low": "0",
      "weatid": "2",
      "weatid1": "2",
      "windid": "1",
      "winpid": "0",
      "weather_iconid": "1",
      "weather_iconid1": "1"
    }
  ]
}

2.2  JSON语法介绍

JSON里就分为两种结构:  对象和数组,通过这两种结构可以表示各种复杂的结构。


JSON语法规则

1. 大括号 { } 用来保存对象

2. 中括号 [ ] 用来保存数组,数组里也可以包含多个对象,对象里又可以包含数组,可以嵌套

3. JSON的值表示语法:  key : value   -->   "width": 1280

4. 多个数据由逗号分隔:  {"width": 1920,"height": 1080}


JSON值可以是以下几种类型:

1. 数字(整数或浮点数)  

2. 字符串(在双引号中)

3. 逻辑值(true 或 false)

4. 数组(在中括号中)

5. 对象(在大括号中)

6. null (空值)


三、cJSON创建简单JSON数据并解析

3.1 新建工程

这是下载下来的cJSON源文件,将它加到自己工程中即可。

image.png

我这里使用VS2017建立工程,演示实例。

image.png

建好工程之后,将文件添加到工程里:

image.png

在VS2017里使用C语言的字符串处理函数会报错,提示不安全;


1>d:\linux-share-dir\vs2017\console_cjsontest\console_cjsontest\cjson.c(155): error C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.


解决办法是:找到【项目属性】,点击【C++】里的【预处理器】,对【预处理器】进行编辑,在里面加入一段代码:_CRT_SECURE_NO_WARNINGS。

image.png

3.2 创建JSON数据

接下来目标是使用cJSON创建出下面这样一个JSON格式数据:

{
  "text": "我是一个字符串数据",
  "number": 666,
  "state1": false,
  "state2": true,
  "state3": null
}

示例代码如下:

image.png

#include <iostream>
//因为当前工程使用的是cpp后缀文件,引用C语言的文件需要使用下面的这种方式
extern "C" {
#include <string.h>
#include <stdio.h>
#include "cJSON.h"
}
int main()
{
  //1. 创建cJSON对象
  cJSON* root = cJSON_CreateObject();
  //2. 创建数据
  cJSON_AddStringToObject(root, "text","我是一个字符串数据");
  cJSON_AddNumberToObject(root,"number",666);
  cJSON_AddBoolToObject(root, "state1", cJSON_False);
  cJSON_AddBoolToObject(root, "state2", cJSON_True);
  cJSON_AddNullToObject(root, "state3");
  //3. 打印生成的结果
  char *json_data=cJSON_PrintUnformatted(root);
  printf("%s\n",json_data);
  //4. 释放空间
  cJSON_Delete(root);
  return 0;
}

image.png

3.3 解析JSON数据

1.#include <iostream>
//因为当前工程使用的是cpp后缀文件,引用C语言的文件需要使用下面的这种方式
extern "C" {
#include <string.h>
#include <stdio.h>
#include "cJSON.h"
}
//将要解析的JSON数据. 
char data[] =
"{"
  "\"text\": \"我是一个字符串数据\","
  "\"number\" : 666,"
  "\"state1\" : false,"
  "\"state2\" : true,"
  "\"state3\" : null"
"}";
int main()
{
  //1. 载入JSON数据
  cJSON* root = cJSON_Parse(data);
  if (root == NULL)return 0;
  //2. 解析字段
  cJSON* item;
  item=cJSON_GetObjectItem(root,"text");
  if (item)
  {
    printf("text=%s\n",item->valuestring);
  }
  item = cJSON_GetObjectItem(root, "number");
  if (item)
  {
    printf("text=%d\n", item->valueint);
  }
  item = cJSON_GetObjectItem(root, "state1");
  if (item)
  {
    printf("state1=%d\n", item->valueint);
  }
  item = cJSON_GetObjectItem(root, "state2");
  if (item)
  {
    printf("state2=%d\n", item->valueint);
  }
  item = cJSON_GetObjectItem(root, "state3");
  if (item)
  {
    printf("state3=%d\n", item->valueint);
  }
  //3. 释放空间
  cJSON_Delete(root);
  return 0;
}

image.png

 四、cJSON创建嵌套的对象数据

目标: 使用cJSON创建出下面这样一个JSON格式数据

1.{
  "data1": {
    "text": "我是一个字符串数据1",
    "number": 666,
    "state1": false,
    "state2": true,
    "state3": null
  },
  "data2": {
    "text": "我是一个字符串数据2",
    "number": 666,
    "state1": false,
    "state2": true,
    "state3": null
  }
}

4.1 创建json数据

#include <iostream>
//因为当前工程使用的是cpp后缀文件,引用C语言的文件需要使用下面的这种方式
extern "C" {
#include <string.h>
#include <stdio.h>
#include "cJSON.h"
}
int main()
{
  //1. 创建cJSON对象
  cJSON* root = cJSON_CreateObject();
  //2. 创建对象数据1
  cJSON* item1 = cJSON_CreateObject();
  cJSON_AddStringToObject(item1, "text","我是一个字符串数据1");
  cJSON_AddNumberToObject(item1,"number",666);
  cJSON_AddBoolToObject(item1, "state1", cJSON_False);
  cJSON_AddBoolToObject(item1, "state2", cJSON_True);
  cJSON_AddNullToObject(item1, "state3");
  cJSON_AddItemToObject(root, "data1", item1);
  //3. 创建对象数据2
  cJSON* item2 = cJSON_CreateObject();
  cJSON_AddStringToObject(item2, "text", "我是一个字符串数据2");
  cJSON_AddNumberToObject(item2, "number", 666);
  cJSON_AddBoolToObject(item2, "state1", cJSON_False);
  cJSON_AddBoolToObject(item2, "state2", cJSON_True);
  cJSON_AddNullToObject(item2, "state3");
  cJSON_AddItemToObject(root, "data2", item2);
  //3. 打印生成的结果
  char *json_data=cJSON_PrintUnformatted(root);
  printf("%s\n",json_data);
  //4. 释放空间
  cJSON_Delete(root);
  return 0;
}

4.2 解析JSON数据

#include <iostream>
//因为当前工程使用的是cpp后缀文件,引用C语言的文件需要使用下面的这种方式
extern "C" {
#include <string.h>
#include <stdio.h>
#include "cJSON.h"
}
//将要解析的JSON数据. 
char data[] =
"{"
  "\"data1\": {"
  "\"text\": \"我是一个字符串数据1\","
  "\"number\" : 666,"
  "\"state1\" : false,"
  "\"state2\" : true,"
  "\"state3\" : null"
   "},"
  "\"data2\": {"
  "\"text\":\"我是一个字符串数据2\","
  "\"number\" : 666,"
  "\"state1\" : false,"
  "\"state2\" : true,"
  "\"state3\" : null"
  "}"
"}";
int main()
{
  //1. 载入JSON数据
  cJSON* root = cJSON_Parse(data);
  if (root == NULL)return 0;
  //2. 解析字段
  cJSON* item;
  item=cJSON_GetObjectItem(root,"data1");
  if (item)
  {
    cJSON *obj;
    obj=cJSON_GetObjectItem(item, "text");
    if (obj)
    {
      printf("text=%s\n", obj->valuestring);
    }
    obj=cJSON_GetObjectItem(item, "number");
    if (obj)
    {
      printf("number=%d\n", obj->valueint);
    }
    obj = cJSON_GetObjectItem(item, "state1");
    if (obj)
    {
      printf("state1=%d\n", obj->valueint);
    }
    obj = cJSON_GetObjectItem(item, "state2");
    if (obj)
    {
      printf("state2=%d\n", obj->valueint);
    }
    obj = cJSON_GetObjectItem(item, "state3");
    if (obj)
    {
      printf("state3=%d\n", obj->valueint);
    }
  }
  item = cJSON_GetObjectItem(root, "data2");
  if (item)
  {
    cJSON *obj;
    obj = cJSON_GetObjectItem(item, "text");
    if (obj)
    {
      printf("text=%s\n", obj->valuestring);
    }
    obj = cJSON_GetObjectItem(item, "number");
    if (obj)
    {
      printf("number=%d\n", obj->valueint);
    }
    obj = cJSON_GetObjectItem(item, "state1");
    if (obj)
    {
      printf("state1=%d\n", obj->valueint);
    }
    obj = cJSON_GetObjectItem(item, "state2");
    if (obj)
    {
      printf("state2=%d\n", obj->valueint);
    }
    obj = cJSON_GetObjectItem(item, "state3");
    if (obj)
    {
      printf("state3=%d\n", obj->valueint);
    }
  }
  //3. 释放空间
  cJSON_Delete(root);
  return 0;
}

image.png

五、cJSON带数组的JSON数据

目标: 使用cJSON创建出下面这样一个JSON格式数据

1.{
  "text": [
    {
      "width": 1280,
      "height": 720
    },
    {
      "width": 1920,
      "height": 1080
    },
    {
      "width": 3840,
      "height": 2160
    }
  ]
}

5.1 创建json数据

#include <iostream>
//因为当前工程使用的是cpp后缀文件,引用C语言的文件需要使用下面的这种方式
extern "C" {
#include <string.h>
#include <stdio.h>
#include "cJSON.h"
}
int main()
{
  cJSON *width = NULL;
  cJSON *height = NULL;
  int i;
  const unsigned int resolution_numbers[3][2] = {
    {1280, 720},
    {1920, 1080},
    {3840, 2160}
  };
  //1. 创建cJSON对象
  cJSON* root = cJSON_CreateObject();
  //2. 创建数组对象
  cJSON *array = cJSON_CreateArray();
  cJSON_AddItemToObject(root, "text", array);
  for (i = 0; i < (sizeof(resolution_numbers) / (2 * sizeof(int))); ++i)
  {
    cJSON *obj = cJSON_CreateObject();
    cJSON_AddItemToArray(array, obj);
    width = cJSON_CreateNumber(resolution_numbers[i][0]);
    cJSON_AddItemToObject(obj, "width", width);
    height = cJSON_CreateNumber(resolution_numbers[i][1]);
    cJSON_AddItemToObject(obj, "height", height);
  }
  //3. 打印生成的结果
  char *json_data=cJSON_PrintUnformatted(root);
  printf("%s\n",json_data);
  //4. 释放空间
  cJSON_Delete(root);
  return 0;
}

5.2 解析JSON数据

#include <iostream>
//因为当前工程使用的是cpp后缀文件,引用C语言的文件需要使用下面的这种方式
extern "C" {
#include <string.h>
#include <stdio.h>
#include "cJSON.h"
}
//将要解析的JSON数据. 
char data[] =
"{"
"\"text\": ["
"{"
"\"width\": 1280,"
"\"height\" : 720"
"},"
"{"
"\"width\": 1920,"
"\"height\" : 1080"
"},"
"{"
"\"width\": 3840,"
"\"height\" : 2160"
"}"
"]"
"}";
int main()
{
  //1. 载入JSON数据
  cJSON* root = cJSON_Parse(data);
  if (root == NULL)return 0;
  //2. 解析字段
  cJSON* item;
  int i;
  item = cJSON_GetObjectItem(root, "text");
  if (item)
  {
    //获取数组的大小
    int ArraySize = cJSON_GetArraySize(item);
    //解析数组的里的每个成员
    for (i = 0; i < ArraySize; i++)
    {
      //取出数组下标对象
      cJSON *array_item = cJSON_GetArrayItem(item, i);
      if (array_item == NULL)continue;
      //解析数据
      cJSON *obj = cJSON_GetObjectItem(array_item, "width");
      if (obj)
      {
        printf("width=%d\n",obj->valueint);
      }
      obj = cJSON_GetObjectItem(array_item, "height");
      if (obj)
      {
        printf("height=%d\n", obj->valueint);
      }
    }
  }
  //3. 释放空间
  cJSON_Delete(root);
  return 0;
}

image.png




目录
相关文章
|
8月前
|
JSON 缓存 自然语言处理
多语言实时数据微店商品详情API:技术实现与JSON数据解析指南
通过以上技术实现与解析指南,开发者可高效构建支持多语言的实时商品详情系统,满足全球化电商场景需求。
|
10月前
|
存储 JSON 关系型数据库
【干货满满】解密 API 数据解析:从 JSON 到数据库存储的完整流程
本文详解电商API开发中JSON数据解析与数据库存储的全流程,涵盖数据提取、清洗、转换及优化策略,结合Python实战代码与主流数据库方案,助开发者构建高效、可靠的数据处理管道。
|
9月前
|
JSON 算法 API
淘宝商品评论API接口核心解析,json数据返回
淘宝商品评论API是淘宝开放平台提供的数据服务接口,允许开发者通过编程方式获取指定商品的用户评价数据,包括文字、图片、视频评论及评分等。其核心价值在于:
|
存储 监控 算法
基于 C++ 哈希表算法实现局域网监控电脑屏幕的数据加速机制研究
企业网络安全与办公管理需求日益复杂的学术语境下,局域网监控电脑屏幕作为保障信息安全、规范员工操作的重要手段,已然成为网络安全领域的关键研究对象。其作用类似网络空间中的 “电子眼”,实时捕获每台电脑屏幕上的操作动态。然而,面对海量监控数据,实现高效数据存储与快速检索,已成为提升监控系统性能的核心挑战。本文聚焦于 C++ 语言中的哈希表算法,深入探究其如何成为局域网监控电脑屏幕数据处理的 “加速引擎”,并通过详尽的代码示例,展现其强大功能与应用价值。
247 2
|
7月前
|
JSON Java Go
【GoGin】(2)数据解析和绑定:结构体分析,包括JSON解析、form解析、URL解析,区分绑定的Bind方法
bind或bindXXX函数(后文中我们统一都叫bind函数)的作用就是将,以方便后续业务逻辑的处理。
452 3
|
11月前
|
JSON 定位技术 PHP
PHP技巧:解析JSON及提取数据
这就是在PHP世界里探索JSON数据的艺术。这场狩猎不仅仅是为了获得数据,而是一种透彻理解数据结构的行动,让数据在你的编码海洋中畅游。通过这次冒险,你已经掌握了打开数据宝箱的钥匙。紧握它,让你在编程世界中随心所欲地航行。
319 67
|
7月前
|
XML JSON 数据处理
超越JSON:Python结构化数据处理模块全解析
本文深入解析Python中12个核心数据处理模块,涵盖csv、pandas、pickle、shelve、struct、configparser、xml、numpy、array、sqlite3和msgpack,覆盖表格处理、序列化、配置管理、科学计算等六大场景,结合真实案例与决策树,助你高效应对各类数据挑战。(238字)
1040 0
|
8月前
|
JSON 自然语言处理 API
多语言实时数据淘宝商品评论API:技术实现与JSON数据解析指南
淘宝商品评论多语言实时采集需结合官方API与后处理技术实现。建议优先通过地域站点适配获取本地化评论,辅以机器翻译完成多语言转换。在合规前提下,企业可构建多语言评论数据库,支撑全球化市场分析与产品优化。
|
存储 C++
UE5 C++:自定义Http节点获取Header数据
综上,通过为UE5创建一个自定义HTTP请求类并覆盖GetResult方法,就能成功地从HTTP响应的Header数据中提取信息。在项目中使用自定义类,不仅可以方便地访问响应头数据,也可随时使用这些信息。希望这种方法可以为你的开发过程带来便利和效益。
527 35
|
缓存 监控 搜索推荐
【实战解析】smallredbook.item_get_video API:小红书视频数据获取与电商应用指南
本文介绍小红书官方API——`smallredbook.item_get_video`的功能与使用方法。该接口可获取笔记视频详情,包括无水印直链、封面图、时长、文本描述、标签及互动数据等,并支持电商场景分析。调用需提供`key`、`secret`和`num_iid`参数,返回字段涵盖视频链接、标题、标签及用户信息等。同时,文章提供了电商实战技巧,如竞品监控与个性化推荐,并列出合规注意事项及替代方案对比。最后解答了常见问题,如笔记ID获取与视频链接时效性等。

热门文章

最新文章

推荐镜像

更多
  • DNS