使用cJSON创建JSON字符串,举例详解。(六)

2024-08-31 09:08

本文主要是介绍使用cJSON创建JSON字符串,举例详解。(六),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

使用cJSON创建JSON字符串

    在Linux下,使用C语言编程,开始JSON字符串的创建。我们还是一步步来,逐渐由简单到复制。  

1,下载源码

可以从如下网站来下载:https://sourceforge.net/projects/cjson/ 。

2,包含cJSON的源码

下载下来,解压后,从里面找到两个文件(cJSON.c、cJSON.h),复制到我们的工程里面。只需在函数中包含头文件(#include “cJSON.h”),然后和cJSON.c一起编译即可使用。 

3,创建一个键值对

         首先是一个简单的键值对字符串,要生成的目标如下:

{"firstName":"Brett"}

要进行创建,就是先确定键与值,然后转为cJSON格式。我们很容易就能明确键为firstName,值为Brett,可是,使用cJSON怎么创建呢? 

对于这个简单的例子,我们需要调用cJSON的五个接口函数就可以实现创建了。(有人不乐意了:都五个函数了,你还说“就可以了”----其实是一法通,百法通,学会了这个创建,其他的创建动作都是非常类似的。)

这五个函数的原型如下:

cJSON*cJSON_CreateObject ();

cJSON*cJSON_CreateString(const char *string);

voidcJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);

voidcJSON_Delete(cJSON *c);

char*cJSON_Print(cJSON *item); 

下面按创建过程来描述一次:

(1)       首先调用cJSON_ CreateObject ()函数,创建一个JSON对象,之后便可向这个对象中添加string或int等内容的数据项了。使用该函数会通过malloc()函数在内存中开辟一个空间,使用完成需要手动释放。

        cJSON*root=cJSON_CreateObject();

(2)       调用cJSON_CreateString ()函数,由一个字符串生成一个cJSON的数据项。

        cJSON*item=cJSON_CreateString("Brett");

(3)       将上一步生成的数据项与其键值("firstName")一起添加到root对象中。

        cJSON_AddItemToObject(root,"firstName",item);

其实到这一步,我们在内存中的cJSON对象就已经构建完成了,后面是展示结果了。

(4)       将cJSON对象的内容解析为字符串,并展示出来。

        out=cJSON_Print(root);

        printf("out:%s\n",out);

(5)       通过cJSON_Delete(),释放cJSON_CreateObject ()分配出来的内存空间。

        cJSON_Delete(root);

(6)       释放cJSON_Print ()分配出来的内存空间。

        free(out); 

         这样就完成了一次cJSON接口调用,实现了字符串的创建工作。

4,转换一个结构体 

接下来,我们来个复杂一点的,将一个结构体转换为JSON字符串,结构体定义如下:

typedefstruct

{

         char firstName[32];

         char lastName[32];

         char email[64];

         int age;

         float height;

} PERSON;

看起来比一个键值对复杂多了,我们又需要学习新的接口函数了吗?

是的,由于出现了数字,我们需要学习一个新函数:

cJSON *cJSON_CreateNumber(double num);

当然,创建的步骤要更复杂一些,下面我仍然是按创建过程来描述一次: 

(1)还是先调用cJSON_ CreateObject ()函数,创建一个JSON对象root,做为根(咱们可以把JSON串看成是一颗树)。使用该函数会通过malloc()函数在内存中开辟一个空间,使用完成需要手动释放。

        cJSON*root=cJSON_CreateObject();

(2)继续调用cJSON_ CreateObject ()函数,创建一个JSON对象obj_person,做为挂载结构体内容的对象。挂载内容之后,这个对象是要挂载到根上的。

        cJSON*obj_person=cJSON_CreateObject();

(3)根据数据生成cJSON格式的数据项,调用cJSON_AddItemToObject()函数挂载到obj_person对象上。这个过程,要多次重复,直到将所有数据都添加上。此时要注意,不同的成员,生成的方法是不一样的。

        cJSON*item=cJSON_CreateString(person->firstName);

        cJSON_AddItemToObject(obj_person,"firstName",item);

        item=cJSON_CreateString(person->lastName);

        cJSON_AddItemToObject(obj_person,"lastName",item);

        item=cJSON_CreateString(person->email);

        cJSON_AddItemToObject(obj_person,"email",item);

        item=cJSON_CreateNumber(person->age);

        cJSON_AddItemToObject(obj_person,"age",item);

        item=cJSON_CreateNumber(person->height);

        cJSON_AddItemToObject(obj_person,"height",item);

(4)将obj_person对象挂载到根上。

        cJSON_AddItemToObject(root,"person",obj_person);

到这一步,我们在内存中的cJSON对象就已经构建完成了,后面就是展示结果。

(5)将cJSON对象的内容解析为字符串,并展示出来。

        out=cJSON_Print(root);

        printf("out:%s\n",out);

(6)通过cJSON_Delete(),释放cJSON_CreateObject ()分配出来的内存空间。这里说明一下,我们前面调用了2次cJSON_CreateObject (),最后只需要针对root调用一次释放即可,因为第二次创建的对象也是挂接在root上的。

        cJSON_Delete(root);

(7)释放cJSON_Print ()分配出来的内存空间。

        free(out); 

         至此,我们就使用cJSON接口完成了由结构体生成JSON字符串的工作。 

5,创建结构体数组的JSON串   

         最后,我们来个更复杂一些的,来转换一个数组,并且数组的成员是结构体!我们要生成的目标如下:

{

"people":[

{"firstName":"z","lastName":"Jason","email":"bbbb@126.com","height":1.67},

{"lastName":"jadena","email":"jadena@126.com","age":8,"height":1.17},

{"email":"cccc@126.com","firstName":"z","lastName":"Juliet","age":36,"height":1.55}

]

此时,我们又需要学习新的接口了,一个是创建数组,一个是取数组成员,函数原型如下:

cJSON*cJSON_CreateArray(void);

void   cJSON_AddItemToArray(cJSON *array, cJSON*item); 

由于前面已经实现了单个结构体的转换,这里我们重点关注下数组的相关调用。 

(1)还是先调用cJSON_ CreateObject ()函数,创建一个JSON对象root,做为根。

(2)调用cJSON_CreateArray ()函数,创建一个JSON数组对象,准备挂载多个结构体对象。挂载内容之后,这个数组对象是要挂载到根上的。

        cJSON*array_person=cJSON_CreateArray();

(3)生成一个结构体对象,并相应添加数据,然后调用cJSON_AddItemToArray()函数挂载到数组对象上。这个过程,要多次重复,直到将所有结构体对象都添加上。

        cJSON_AddItemToArray(array_person,obj_person);

(4)将数组对象挂载到根上。

        cJSON_AddItemToObject(root,"people",array_person);

到这一步,我们在内存中的cJSON对象就已经构建完成了。

(5)将cJSON对象的内容解析为字符串,并展示出来。

(6)通过cJSON_Delete(),释放cJSON_CreateObject ()分配出来的内存空间。

(7)释放cJSON_Print ()分配出来的内存空间。

         这样,我们就使用cJSON接口完成了将结构体数组转换成JSON字符串的工作。

详细代码见后文附带例程。         

说明:

本文所附带例程,实现了结构体数组生成JSON字符串,只是一个学习之作,对于初学cJSON的同学,可以有些借鉴参考的作用。 

附带例程: 

[cpp] view plain copy

  1. #include <stdio.h>  
  2. #include <string.h>  
  3. #include <sys/types.h>  
  4. #include <stdlib.h>  
  5. #include <unistd.h>  
  6.   
  7. #include "cJSON.h"  
  8.   
  9. typedef struct  
  10. {  
  11.     int id;  
  12.     char firstName[32];  
  13.     char lastName[32];  
  14.     char email[64];  
  15.     int age;  
  16.     float height;  
  17. }people;  
  18.   
  19. void dofile(char *filename);/* Read a file, parse, render back, etc. */  
  20.   
  21. int main(int argc, char **argv)  
  22. {  
  23.   
  24.     dofile("json_str4.txt");  
  25.   
  26.     return 0;  
  27. }  
  28.   
  29.   
  30. //create a key-value pair  
  31. int str_to_cJSON(char *json_string, char *str_val)  
  32. {  
  33.     char * out=NULL;  
  34.     cJSON *root=cJSON_CreateObject();  
  35.     if (!root)  
  36.     {  
  37.         printf("Error before: [%s]\n",cJSON_GetErrorPtr());  
  38.         return -1;  
  39.     }  
  40.     else  
  41.     {  
  42.         cJSON *item=cJSON_CreateString("Brett");  
  43.         cJSON_AddItemToObject(root,"firstName",item);  
  44.   
  45.         out=cJSON_Print(root);  
  46.         printf("out2:%s\n",out);  
  47.   
  48.         cJSON_Delete(root);  
  49.         if(out!=NULL)  
  50.         {  
  51.             free(out);  
  52.         }  
  53.     }  
  54.     return 0;  
  55. }  
  56.   
  57. //create a object from struct  
  58. int struct_to_cJSON(char *json_string, people *person)  
  59. {  
  60.   
  61.     if((json_string==NULL) || (person==NULL))  
  62.     {  
  63.         printf("%s: input is invalid",__func__);  
  64.     }  
  65.   
  66.     char * out=NULL;  
  67.     cJSON *root=cJSON_CreateObject();  
  68.   
  69.     if (!root)  
  70.     {  
  71.         printf("Error before: [%s]\n",cJSON_GetErrorPtr());  
  72.         return -1;  
  73.     }  
  74.     else  
  75.     {  
  76.         cJSON *obj_person=cJSON_CreateObject();  
  77.   
  78.         cJSON *item=cJSON_CreateString(person->firstName);  
  79.         cJSON_AddItemToObject(obj_person,"firstName",item);  
  80.   
  81.         item=cJSON_CreateString(person->lastName);  
  82.         cJSON_AddItemToObject(obj_person,"lastName",item);  
  83.   
  84.         item=cJSON_CreateString(person->email);  
  85.         cJSON_AddItemToObject(obj_person,"email",item);  
  86.   
  87.         item=cJSON_CreateNumber(person->age);  
  88.         cJSON_AddItemToObject(obj_person,"age",item);  
  89.   
  90.         item=cJSON_CreateNumber(person->height);  
  91.         cJSON_AddItemToObject(obj_person,"height",item);  
  92.   
  93.         cJSON_AddItemToObject(root,"person",obj_person);  
  94.   
  95.         out=cJSON_Print(root);  
  96.         printf("out2:%s\n",out);  
  97.   
  98.         cJSON_Delete(root);  
  99.         if(out!=NULL)  
  100.         {  
  101.             memcpy(json_string,out,strlen(out));  
  102.             free(out);  
  103.         }  
  104.     }  
  105.   
  106.     return 0;  
  107. }  
  108.   
  109.   
  110. //a struct array to CJSON  
  111. int struct_array_to_cJSON(char *text, people worker[])  
  112. {  
  113.     cJSON *json,*arrayItem,*item,*object;  
  114.     int i;  
  115.   
  116.     for(i=0;i<3;i++)  
  117.     {  
  118.         printf("i=%d, firstName=%s,lastName=%s,email=%s,age=%d,height=%f\n",  
  119.                 i,  
  120.                 worker[i].firstName,  
  121.                 worker[i].lastName,  
  122.                 worker[i].email,  
  123.                 worker[i].age,  
  124.                 worker[i].height);  
  125.     }  
  126.   
  127.     if((text==NULL) || (worker==NULL))  
  128.     {  
  129.         printf("%s: input is invalid",__func__);  
  130.     }  
  131.   
  132.     char * out=NULL;  
  133.     cJSON *root=cJSON_CreateObject();  
  134.   
  135.     if (!root)  
  136.     {  
  137.         printf("Error before: [%s]\n",cJSON_GetErrorPtr());  
  138.         return -1;  
  139.     }  
  140.     else  
  141.     {  
  142.         cJSON *array_person=cJSON_CreateArray();  
  143.   
  144.         for(i=0;i<3;i++)  
  145.         {  
  146.             cJSON *obj_person=cJSON_CreateObject();  
  147.   
  148.             cJSON *item=cJSON_CreateString(worker[i].firstName);  
  149.             cJSON_AddItemToObject(obj_person,"firstName",item);  
  150.   
  151.             item=cJSON_CreateString(worker[i].lastName);  
  152.             cJSON_AddItemToObject(obj_person,"lastName",item);  
  153.   
  154.             item=cJSON_CreateString(worker[i].email);  
  155.             cJSON_AddItemToObject(obj_person,"email",item);  
  156.   
  157.             item=cJSON_CreateNumber(worker[i].age);  
  158.             cJSON_AddItemToObject(obj_person,"age",item);  
  159.   
  160.             item=cJSON_CreateNumber(worker[i].height);  
  161.             cJSON_AddItemToObject(obj_person,"height",item);  
  162.   
  163.             cJSON_AddItemToArray(array_person,obj_person);  
  164.         }  
  165.   
  166.         cJSON_AddItemToObject(root,"people",array_person);  
  167.   
  168.         out=cJSON_Print(root);  
  169.         printf("out:%s\n",out);  
  170.   
  171.         cJSON_Delete(root);  
  172.         if(out!=NULL)  
  173.         {  
  174.             memcpy(text,out,strlen(out));  
  175.             free(out);  
  176.         }  
  177.     }  
  178.   
  179.     return 0;  
  180. }  
  181.   
  182. // create CJSON, write file  
  183. void dofile(char *filename)  
  184. {  
  185.     FILE *f;  
  186.     int len;  
  187.     char data[1024];  
  188.       
  189.     f=fopen(filename,"wb");  
  190.     fseek(f,0,SEEK_END);  
  191.     len=ftell(f);  
  192.     fseek(f,0,SEEK_SET);  
  193.       
  194.     printf("read file %s complete, len=%d.\n",filename,len);  
  195.   
  196. //  char str_name[40];  
  197. //  int ret = str_to_cJSON(data, str_name);  
  198.   
  199.     people worker[3]={  
  200.             {0,"zhong","Jason","bbbb@126.com",0,1.67},  
  201.             {1,"","jadena","jadena@126.com",8,1.17},  
  202.             {2,"zhu","Juliet","cccc@126.com",36,1.55}  
  203.     };  
  204. //  struct_to_cJSON(data, &worker[1]);  
  205.     struct_array_to_cJSON(data, worker);  
  206.   
  207.     fwrite(data,1,strlen(data),f);  
  208.     fclose(f);  
  209.   

 

 

 

http://blog.csdn.net/lintax/article/details/51549345

 

这篇关于使用cJSON创建JSON字符串,举例详解。(六)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1123473

相关文章

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

pdfmake生成pdf的使用

实际项目中有时会有根据填写的表单数据或者其他格式的数据,将数据自动填充到pdf文件中根据固定模板生成pdf文件的需求 文章目录 利用pdfmake生成pdf文件1.下载安装pdfmake第三方包2.封装生成pdf文件的共用配置3.生成pdf文件的文件模板内容4.调用方法生成pdf 利用pdfmake生成pdf文件 1.下载安装pdfmake第三方包 npm i pdfma

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]