cJSON-轻量级解析模块、字符串的神——编织STM32C8T6与阿里云信息传递的纽带

server/2024/9/19 7:19:53/ 标签: json, c, stm32, C8T6, 阿里云, 字符串
cle class="baidu_pl">
cle_content" class="article_content clearfix">
content_views" class="htmledit_views">

     color:#ed7976;">   编写方向:本人就不泛泛的编写一篇什么一文学会cJSON了࿰c;没什么突出点࿰c;也就我水水字数࿰c;你们看来看去也不懂࿰c;本人是从上阿里云传信息接触的cJSON的࿰c;我就此写一篇针对性的文章࿰c;希望对大家有用࿰c;后期我在其他方面用到还会继续更新。

一、简介

        cJSON是一个用C语言编写的轻量级JSON解析器和生成器库。它由Derek M. Jones创建࿰c;旨在为C程序员提供一种简单的方法来处理JSON数据。cJSON的主要特点包括:

  • 易用性cJSON设计得非常直观࿰c;使得JSON对象的创建和处理变得简单直接。
  • 动态内存管理cJSON内部会自动管理内存分配与释放࿰c;简化了用户代码。
  • 错误处理:能够报告解析错误的位置和其他相关信息。
  • 支持完整的JSON数据类型:包括数字、字符串、布尔值、数组、对象等。

        使用cJSON࿰c;你可以轻松地创建JSON对象࿰c;添加键值对࿰c;然后将其转换为字符串。相反࿰c;你也可以解析JSON字符串c;提取其中的值࿰c;并根据需要操作它们。

二、解决的问题

        1、问题阐述

        首先我先阐述一下我遇到的问题:我在用以下这种格式(图-1)上传动态数据到阿里云端的时候发现—“字符串%s“—形式的数据上传的时候不被识别࿰c;如(图-2)所示

c="https://i-blog.csdnimg.cn/direct/b7cad940b07343dd8e13786fbedb98ee.png" width="1200" />

center;">图-1 

class="img-center">c="https://i-blog.csdnimg.cn/direct/80bea1d2ba7644fe9f90319db4a34313.png" width="542" />

center;">图-2

         sprintf基本用法及示例:

        是 C 语言中的一个标准库函数࿰c;用于格式化输出到一个字符串中。它的工作方式类似于 <code>printfcode> 函数࿰c;但是输出不是发送到标准输出设备(通常是屏幕)࿰c;而是写入到一个字符数组中。

        示例:

<code class="language-cpp">#include <stdio.h>
#include <string.h>int main() {int num = 42;char str[20];sprintf(str, "The answer is %d", num);printf("%s\n", str);  // 输出: The answer is 42return 0;
}code>

三、cJSON构建传输字符串 

        1、完整的构建代码:希望大家阅读代码的时候࿰c;可以把代码复制出去࿰c;然后对照着我下面的讲解看

<code class="language-cpp">void set_temp_humid(void)
{/*定义变量࿰c;定义需要上传的各类信息࿰c;我这里就先以固定数实现数据上传*/int humid = 1;int temperature = 1;char ID[10];IC_IDGet(ID);u1_printf ("%s",ID);/*定义用来存放构建的JSON转化的字符串*/char *str = NULL; // 指向JSON字符串的指针/*此处用cJSON结构体定义一个对象࿰c;用来存放需要构建的信息*/cJSON *class="tags" href="/JSON.html" title=json>json = cJSON_CreateObject(); // 创建一个空的JSON对象cJSON *params_cclass="tags" href="/JSON.html" title=json>json = cJSON_CreateObject(); // 创建一个空的子JSON对象// 向子JSON对象添加数据cJSON_AddNumberToObject(params_cclass="tags" href="/JSON.html" title=json>json, "humid", humid);cJSON_AddNumberToObject(params_cclass="tags" href="/JSON.html" title=json>json, "temp", temperature);cJSON_AddStringToObject(params_cclass="tags" href="/JSON.html" title=json>json, "ID", ID);// 向主JSON对象添加数据cJSON_AddItemToObject(class="tags" href="/JSON.html" title=json>json, "method", cJSON_CreateString("thing.service.property.post"));cJSON_AddItemToObject(class="tags" href="/JSON.html" title=json>json, "id", cJSON_CreateString("99119635"));cJSON_AddItemToObject(class="tags" href="/JSON.html" title=json>json, "params", params_cclass="tags" href="/JSON.html" title=json>json);cJSON_AddItemToObject(class="tags" href="/JSON.html" title=json>json, "version", cJSON_CreateString("1.0.0"));// 将JSON对象转换为无格式的字符串str = cJSON_PrintUnformatted(class="tags" href="/JSON.html" title=json>json);// 打印JSON格式的字符串u1_printf("class="tags" href="/JSON.html" title=json>json格式 = %s\r\n", str);MQTT_PublishQs0(P_TOPIC_NAME,str,strlen(str));    //添加数据࿰c;发布给服务器	// 清理JSON对象占用的内存cJSON_Delete(class="tags" href="/JSON.html" title=json>json);// 如果分配了额外的字符串空间࿰c;释放它if(str != NULL){free(str);str = NULL;u1_printf("释放str空间成功\r\n");}Delay_ms(1000);}code>

2、详细讲解

        第一步:

        先对需要上传的信息变量进行定义࿰c;用来接收各个传感器模块收集到的动态数据 

c="https://i-blog.csdnimg.cn/direct/161c0a197b2545b98c36ca083007c61f.png" width="857" />

        第二步:

        定义一个可以接收自己后面构建的JSON字符串转化成的无格式字符串

c="https://i-blog.csdnimg.cn/direct/d034044276df4a6a94e99dc2f506b23d.png" width="819" />

        第三步:

        用cJSON结构体 定义空的主JSON对象和子JSON对象

c="https://i-blog.csdnimg.cn/direct/8642825686594cadb7b288f21954e109.png" width="1029" />

         第四步:

        分别向子JSON对象和主JSON对象添加要构建的数据        

c="https://i-blog.csdnimg.cn/direct/4135eaefc7f1413fbea59002e7f602f5.png" width="1200" />

        第五步:

        转换JSON对象为无格式的字符串并存入前面定义的str指针

c="https://i-blog.csdnimg.cn/direct/cf0e32e8b1cf4fb3a63b558a99c71613.png" width="1009" />

        第六步:

        一定要将“ JSON “对象和存储无格式字符串用的指针 str 清空࿰c;要不然会造成占用内存导致卡机c="https://i-blog.csdnimg.cn/direct/86efaaaa0bb045ae8bbbc49535fe5095.png" width="949" />

四、相关函数详解 

<code>①、cJSON_CreateObject()code>

        是一个用于创建 JSON 对象的基础函数       

        具体用法如下:

c="https://i-blog.csdnimg.cn/direct/f31e0f00ad2544f1b5deaae864b85f24.png" width="1044" />

②、向JSON对象中添加数据的几类函数

  1. <code>cJSON_AddNullToObject(object, name)code>

    • 作用:向 JSON 对象中添加一个 <code>nullcode> 值。
    • 参数
      • <code>objectcode>:指向 cJSON 结构体的指针࿰c;表示要添加 null 值的目标 JSON 对象。
      • <code>namecode>:键名(字符串)࿰c;表示 null 值对应的键。
  2. <code>cJSON_AddTrueToObject(object, name)code>

    • 作用:向 JSON 对象中添加一个布尔值 <code>truecode>。
    • 参数
      • <code>objectcode>:指向 cJSON 结构体的指针࿰c;表示要添加 true 值的目标 JSON 对象。
      • <code>namecode>:键名(字符串)࿰c;表示 true 值对应的键。
  3. <code>cJSON_AddFalseToObject(object, name)code>

    • 作用:向 JSON 对象中添加一个布尔值 <code>falsecode>。
    • 参数
      • <code>objectcode>:指向 cJSON 结构体的指针࿰c;表示要添加 false 值的目标 JSON 对象。
      • <code>namecode>:键名(字符串)࿰c;表示 false 值对应的键。
  4. <code>cJSON_AddBoolToObject(object, name, b)code>

    • 作用:向 JSON 对象中添加一个布尔值࿰c;可以是 <code>truecode> 或 <code>falsecode>。
    • 参数
      • <code>objectcode>:指向 cJSON 结构体的指针࿰c;表示要添加布尔值的目标 JSON 对象。
      • <code>namecode>:键名(字符串)࿰c;表示布尔值对应的键。
      • <code>bcode>:布尔值࿰c;可以是 <code>truecode> 或 <code>falsecode>(通常为 <code>1code> 或 <code>0code>)。
  5. <code>cJSON_AddNumberToObject(object, name, n)code>

    • 作用:向 JSON 对象中添加一个数值。
    • 参数
      • <code>objectcode>:指向 cJSON 结构体的指针࿰c;表示要添加数值的目标 JSON 对象。
      • <code>namecode>:键名(字符串)࿰c;表示数值对应的键。
      • <code>ncode>:数值(通常是 <code>doublecode> 类型)࿰c;表示要添加的数值。
  6. <code>cJSON_AddStringToObject(object, name, s)code>

    • 作用:向 JSON 对象中添加一个字符串值。
    • 参数
      • <code>objectcode>:指向 cJSON 结构体的指针࿰c;表示要添加字符串值的目标 JSON 对象。
      • <code>namecode>:键名(字符串)࿰c;表示字符串值对应的键。
      • <code>scode>:字符串值(通常是 <code>char *code> 类型)࿰c;表示要添加的字符串

        具体应用:

<code class="language-cpp">#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "Serial.h"
#include "led.h"
#include "cJSON.h"uint8_t RxData;			//定义用于接收串口数据的变量int main(void)
{/*串口初始化*/Serial_Init();while (1){cJSON *class="tags" href="/JSON.html" title=json>json = cJSON_CreateObject();// 向 JSON 对象中添加不同类型的值cJSON_AddStringToObject(class="tags" href="/JSON.html" title=json>json, "name", "Alice");cJSON_AddNumberToObject(class="tags" href="/JSON.html" title=json>json, "age", 25);cJSON_AddBoolToObject(class="tags" href="/JSON.html" title=json>json, "is_student", 1);cJSON_AddNullToObject(class="tags" href="/JSON.html" title=json>json, "job");cJSON_AddTrueToObject(class="tags" href="/JSON.html" title=json>json, "is_active");cJSON_AddFalseToObject(class="tags" href="/JSON.html" title=json>json, "is_admin");// 打印 JSON 对象Serial_Printf("%s\n", cJSON_Print(class="tags" href="/JSON.html" title=json>json));// 清理内存cJSON_Delete(class="tags" href="/JSON.html" title=json>json);Delay_ms(100);}}code>

        结果显示: 

class="img-center">c="https://i-blog.csdnimg.cn/direct/7e13951dbf28474bb23c5a4335a61638.png" width="293" />

③、cJSON_PrintUnformatted()

        是 cJSON 库中的一个函数࿰c;用于将 cJSON 结构体转换为一个未格式化的 JSON 字符串

        具体用法:

c="https://i-blog.csdnimg.cn/direct/2a28a7c1b9274436a80ba1214fe24d56.png" width="730" />

④、free、cJSON_Delete()

        free是 C 标准库中的一个函数࿰c;用于释放之前通过 <code>malloccode>、<code>calloccode> 或 <code>realloccode> 动态分配的内存块。

<code>  cJSON_Deletecode> 是 cJSON 库提供的一个专用函数࿰c;用于释放 cJSON 结构体及其关联的所有内存。当你使用 cJSON 库创建了 JSON 对象或数组时࿰c;应该使用 <code>cJSON_Deletecode> 来释放这些对象占用的内存。

        具体用法:

c="https://i-blog.csdnimg.cn/direct/e9f1def26fcb4657b632719ca60f5d7b.png" width="724" />

五、以STM32C8T6为核心的构建过程可能会产生的问题 

       1、当你的项目代码很多时会出现的相关问题

        因为代码过多࿰c;单片机的内存资源有限࿰c;如果之前没有做过改变空间资源等先关操作的人第一次可能会发现࿰c;将代码移植到一个简单工程中的时候࿰c;可以正常运行࿰c;但是当自己移植到一个相对复杂的程序中时࿰c;整个程序好像不动了࿰c;串口打印也消失了࿰c;这个时候就是ckground-color:#38d8f0;">内存分配的原因导致的。可以从以下这个地方改动来匹配自己的程序。

        ①、找到后缀为 ckground-color:#38d8f0;">.sckground-color:#38d8f0;"> 的这个文件࿰c;这是单片机的启动文件

class="img-center">c="https://i-blog.csdnimg.cn/direct/5c9c760003624b3c8d83fde6829d71bc.png" width="332" />

        ②、修改以下箭头指的地方࿰c;正常来说这里应该是0x00000200,我这里是根据我的工作做了修改࿰c;大家可以根据自己的工程需要分配大小

c="https://i-blog.csdnimg.cn/direct/a5825b50263a43edaf8e260bf5f1a5c8.png" width="822" />

六、cJSON源码

         cJSON.c

<code class="language-cpp">/*Copyright (c) 2009 Dave GamblePermission is hereby granted, free of charge, to any person obtaining a copyof this software and associated documentation files (the "Software"), to dealin the Software without restriction, including without limitation the rightsto use, copy, modify, merge, publish, distribute, sublicense, and/or sellcopies of the Software, and to permit persons to whom the Software isfurnished to do so, subject to the following conditions:The above copyright notice and this permission notice shall be included inall copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ORIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THEAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHERLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS INTHE SOFTWARE.
*//* cJSON */
/* JSON parser in C. */#include <string.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <float.h>
#include <limits.h>
#include <ctype.h>
#include "cJSON.h"static const char *ep;const char *cJSON_GetErrorPtr(void) {return ep;}static int cJSON_strcasecmp(const char *s1,const char *s2)
{if (!s1) return (s1==s2)?0:1;if (!s2) return 1;for(; tolower(*s1) == tolower(*s2); ++s1, ++s2)	if(*s1 == 0)	return 0;return tolower(*(const unsigned char *)s1) - tolower(*(const unsigned char *)s2);
}static void *(*cJSON_malloc)(size_t sz) = malloc;
static void (*cJSON_free)(void *ptr) = free;static char* cJSON_strdup(const char* str)
{size_t len;char* copy;len = strlen(str) + 1;if (!(copy = (char*)cJSON_malloc(len))) return 0;memcpy(copy,str,len);return copy;
}void cJSON_InitHooks(cJSON_Hooks* hooks)
{if (!hooks) { /* Reset hooks */cJSON_malloc = malloc;cJSON_free = free;return;}cJSON_malloc = (hooks->malloc_fn)?hooks->malloc_fn:malloc;cJSON_free	 = (hooks->free_fn)?hooks->free_fn:free;
}/* Internal constructor. */
static cJSON *cJSON_New_Item(void)
{cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON));if (node) memset(node,0,sizeof(cJSON));return node;
}/* Delete a cJSON structure. */
void cJSON_Delete(cJSON *c)
{cJSON *next;while (c){next=c->next;if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child);if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring);if (!(c->type&cJSON_StringIsConst) && c->string) cJSON_free(c->string);cJSON_free(c);c=next;}
}/* Parse the input text to generate a number, and populate the result into item. */
static const char *parse_number(cJSON *item,const char *num)
{double n=0,sign=1,scale=0;int subscale=0,signsubscale=1;if (*num=='-') sign=-1,num++;	/* Has sign? */if (*num=='0') num++;			/* is zero */if (*num>='1' && *num<='9')	do	n=(n*10.0)+(*num++ -'0');	while (*num>='0' && *num<='9');	/* Number? */if (*num=='.' && num[1]>='0' && num[1]<='9') {num++;		do	n=(n*10.0)+(*num++ -'0'),scale--; while (*num>='0' && *num<='9');}	/* Fractional part? */if (*num=='e' || *num=='E')		/* Exponent? */{	num++;if (*num=='+') num++;	else if (*num=='-') signsubscale=-1,num++;		/* With sign? */while (*num>='0' && *num<='9') subscale=(subscale*10)+(*num++ - '0');	/* Number? */}n=sign*n*pow(10.0,(scale+subscale*signsubscale));	/* number = +/- number.fraction * 10^+/- exponent */item->valuedouble=n;item->valueint=(int)n;item->type=cJSON_Number;return num;
}static int pow2gt (int x)	{	--x;	x|=x>>1;	x|=x>>2;	x|=x>>4;	x|=x>>8;	x|=x>>16;	return x+1;	}typedef struct {char *buffer; int length; int offset; } printbuffer;static char* ensure(printbuffer *p,int needed)
{char *newbuffer;int newsize;if (!p || !p->buffer) return 0;needed+=p->offset;if (needed<=p->length) return p->buffer+p->offset;newsize=pow2gt(needed);newbuffer=(char*)cJSON_malloc(newsize);if (!newbuffer) {cJSON_free(p->buffer);p->length=0,p->buffer=0;return 0;}if (newbuffer) memcpy(newbuffer,p->buffer,p->length);cJSON_free(p->buffer);p->length=newsize;p->buffer=newbuffer;return newbuffer+p->offset;
}static int update(printbuffer *p)
{char *str;if (!p || !p->buffer) return 0;str=p->buffer+p->offset;return p->offset+strlen(str);
}/* Render the number nicely from the given item into a string. */
static char *print_number(cJSON *item,printbuffer *p)
{char *str=0;double d=item->valuedouble;if (d==0){if (p)	str=ensure(p,2);else	str=(char*)cJSON_malloc(2);	/* special case for 0. */if (str) strcpy(str,"0");}else if (fabs(((double)item->valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN){if (p)	str=ensure(p,21);else	str=(char*)cJSON_malloc(21);	/* 2^64+1 can be represented in 21 chars. */if (str)	sprintf(str,"%d",item->valueint);}else{if (p)	str=ensure(p,64);else	str=(char*)cJSON_malloc(64);	/* This is a nice tradeoff. */if (str){if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60)sprintf(str,"%.0f",d);else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9)			sprintf(str,"%e",d);else												sprintf(str,"%f",d);}}return str;
}static unsigned parse_hex4(const char *str)
{unsigned h=0;if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;h=h<<4;str++;if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;h=h<<4;str++;if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;h=h<<4;str++;if (*str>='0' && *str<='9') h+=(*str)-'0'; else if (*str>='A' && *str<='F') h+=10+(*str)-'A'; else if (*str>='a' && *str<='f') h+=10+(*str)-'a'; else return 0;return h;
}/* Parse the input text into an unescaped cstring, and populate item. */
static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
static const char *parse_string(cJSON *item,const char *str)
{const char *ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2;if (*str!='\"') {ep=str;return 0;}	/* not a string! */while (*ptr!='\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++;	/* Skip escaped quotes. */out=(char*)cJSON_malloc(len+1);	/* This is how long we need for the string, roughly. */if (!out) return 0;ptr=str+1;ptr2=out;while (*ptr!='\"' && *ptr){if (*ptr!='\\') *ptr2++=*ptr++;else{ptr++;switch (*ptr){case 'b': *ptr2++='\b';	break;case 'f': *ptr2++='\f';	break;case 'n': *ptr2++='\n';	break;case 'r': *ptr2++='\r';	break;case 't': *ptr2++='\t';	break;case 'u':	 /* transcode utf16 to utf8. */uc=parse_hex4(ptr+1);ptr+=4;	/* get the unicode char. */if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0)	break;	/* check for invalid.	*/if (uc>=0xD800 && uc<=0xDBFF)	/* UTF16 surrogate pairs.	*/{if (ptr[1]!='\\' || ptr[2]!='u')	break;	/* missing second-half of surrogate.	*/uc2=parse_hex4(ptr+3);ptr+=6;if (uc2<0xDC00 || uc2>0xDFFF)		break;	/* invalid second-half of surrogate.	*/uc=0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF));}len=4;if (uc<0x80) len=1;else if (uc<0x800) len=2;else if (uc<0x10000) len=3; ptr2+=len;switch (len) {case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6;case 1: *--ptr2 =(uc | firstByteMark[len]);}ptr2+=len;break;default:  *ptr2++=*ptr; break;}ptr++;}}*ptr2=0;if (*ptr=='\"') ptr++;item->valuestring=out;item->type=cJSON_String;return ptr;
}/* Render the cstring provided to an escaped version that can be printed. */
static char *print_string_ptr(const char *str,printbuffer *p)
{const char *ptr;char *ptr2,*out;int len=0,flag=0;unsigned char token;for (ptr=str;*ptr;ptr++) flag|=((*ptr>0 && *ptr<32)||(*ptr=='\"')||(*ptr=='\\'))?1:0;if (!flag){len=ptr-str;if (p) out=ensure(p,len+3);else		out=(char*)cJSON_malloc(len+3);if (!out) return 0;ptr2=out;*ptr2++='\"';strcpy(ptr2,str);ptr2[len]='\"';ptr2[len+1]=0;return out;}if (!str){if (p)	out=ensure(p,3);else	out=(char*)cJSON_malloc(3);if (!out) return 0;strcpy(out,"\"\"");return out;}ptr=str;while ((token=*ptr) && ++len) {if (strchr("\"\\\b\f\n\r\t",token)) len++; else if (token<32) len+=5;ptr++;}if (p)	out=ensure(p,len+3);else	out=(char*)cJSON_malloc(len+3);if (!out) return 0;ptr2=out;ptr=str;*ptr2++='\"';while (*ptr){if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') *ptr2++=*ptr++;else{*ptr2++='\\';switch (token=*ptr++){case '\\':	*ptr2++='\\';	break;case '\"':	*ptr2++='\"';	break;case '\b':	*ptr2++='b';	break;case '\f':	*ptr2++='f';	break;case '\n':	*ptr2++='n';	break;case '\r':	*ptr2++='r';	break;case '\t':	*ptr2++='t';	break;default: sprintf(ptr2,"u%04x",token);ptr2+=5;	break;	/* escape and print */}}}*ptr2++='\"';*ptr2++=0;return out;
}
/* Invote print_string_ptr (which is useful) on an item. */
static char *print_string(cJSON *item,printbuffer *p)	{return print_string_ptr(item->valuestring,p);}/* Predeclare these prototypes. */
static const char *parse_value(cJSON *item,const char *value);
static char *print_value(cJSON *item,int depth,int fmt,printbuffer *p);
static const char *parse_array(cJSON *item,const char *value);
static char *print_array(cJSON *item,int depth,int fmt,printbuffer *p);
static const char *parse_object(cJSON *item,const char *value);
static char *print_object(cJSON *item,int depth,int fmt,printbuffer *p);/* Utility to jump whitespace and cr/lf */
static const char *skip(const char *in) {while (in && *in && (unsigned char)*in<=32) in++; return in;}/* Parse an object - create a new root, and populate. */
cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated)
{const char *end=0;cJSON *c=cJSON_New_Item();ep=0;if (!c) return 0;       /* memory fail */end=parse_value(c,skip(value));if (!end)	{cJSON_Delete(c);return 0;}	/* parse failure. ep is set. *//* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */if (require_null_terminated) {end=skip(end);if (*end) {cJSON_Delete(c);ep=end;return 0;}}if (return_parse_end) *return_parse_end=end;return c;
}
/* Default options for cJSON_Parse */
cJSON *cJSON_Parse(const char *value) {return cJSON_ParseWithOpts(value,0,0);}/* Render a cJSON item/entity/structure to text. */
char *cJSON_Print(cJSON *item)				{return print_value(item,0,1,0);}
char *cJSON_PrintUnformatted(cJSON *item)	{return print_value(item,0,0,0);}char *cJSON_PrintBuffered(cJSON *item,int prebuffer,int fmt)
{printbuffer p;p.buffer=(char*)cJSON_malloc(prebuffer);p.length=prebuffer;p.offset=0;return print_value(item,0,fmt,&p);return p.buffer;
}/* Parser core - when encountering text, process appropriately. */
static const char *parse_value(cJSON *item,const char *value)
{if (!value)						return 0;	/* Fail on null. */if (!strncmp(value,"null",4))	{ item->type=cJSON_NULL;  return value+4; }if (!strncmp(value,"false",5))	{ item->type=cJSON_False; return value+5; }if (!strncmp(value,"true",4))	{ item->type=cJSON_True; item->valueint=1;	return value+4; }if (*value=='\"')				{ return parse_string(item,value); }if (*value=='-' || (*value>='0' && *value<='9'))	{ return parse_number(item,value); }if (*value=='[')				{ return parse_array(item,value); }if (*value=='{')				{ return parse_object(item,value); }ep=value;return 0;	/* failure. */
}/* Render a value to text. */
static char *print_value(cJSON *item,int depth,int fmt,printbuffer *p)
{char *out=0;if (!item) return 0;if (p){switch ((item->type)&255){case cJSON_NULL:	{out=ensure(p,5);	if (out) strcpy(out,"null");	break;}case cJSON_False:	{out=ensure(p,6);	if (out) strcpy(out,"false");	break;}case cJSON_True:	{out=ensure(p,5);	if (out) strcpy(out,"true");	break;}case cJSON_Number:	out=print_number(item,p);break;case cJSON_String:	out=print_string(item,p);break;case cJSON_Array:	out=print_array(item,depth,fmt,p);break;case cJSON_Object:	out=print_object(item,depth,fmt,p);break;}}else{switch ((item->type)&255){case cJSON_NULL:	out=cJSON_strdup("null");	break;case cJSON_False:	out=cJSON_strdup("false");break;case cJSON_True:	out=cJSON_strdup("true"); break;case cJSON_Number:	out=print_number(item,0);break;case cJSON_String:	out=print_string(item,0);break;case cJSON_Array:	out=print_array(item,depth,fmt,0);break;case cJSON_Object:	out=print_object(item,depth,fmt,0);break;}}return out;
}/* Build an array from input text. */
static const char *parse_array(cJSON *item,const char *value)
{cJSON *child;if (*value!='[')	{ep=value;return 0;}	/* not an array! */item->type=cJSON_Array;value=skip(value+1);if (*value==']') return value+1;	/* empty array. */item->child=child=cJSON_New_Item();if (!item->child) return 0;		 /* memory fail */value=skip(parse_value(child,skip(value)));	/* skip any spacing, get the value. */if (!value) return 0;while (*value==','){cJSON *new_item;if (!(new_item=cJSON_New_Item())) return 0; 	/* memory fail */child->next=new_item;new_item->prev=child;child=new_item;value=skip(parse_value(child,skip(value+1)));if (!value) return 0;	/* memory fail */}if (*value==']') return value+1;	/* end of array */ep=value;return 0;	/* malformed. */
}/* Render an array to text */
static char *print_array(cJSON *item,int depth,int fmt,printbuffer *p)
{char **entries;char *out=0,*ptr,*ret;int len=5;cJSON *child=item->child;int numentries=0,i=0,fail=0;size_t tmplen=0;/* How many entries in the array? */while (child) numentries++,child=child->next;/* Explicitly handle numentries==0 */if (!numentries){if (p)	out=ensure(p,3);else	out=(char*)cJSON_malloc(3);if (out) strcpy(out,"[]");return out;}if (p){/* Compose the output array. */i=p->offset;ptr=ensure(p,1);if (!ptr) return 0;	*ptr='[';	p->offset++;child=item->child;while (child && !fail){print_value(child,depth+1,fmt,p);p->offset=update(p);if (child->next) {len=fmt?2:1;ptr=ensure(p,len+1);if (!ptr) return 0;*ptr++=',';if(fmt)*ptr++=' ';*ptr=0;p->offset+=len;}child=child->next;}ptr=ensure(p,2);if (!ptr) return 0;	*ptr++=']';*ptr=0;out=(p->buffer)+i;}else{/* Allocate an array to hold the values for each */entries=(char**)cJSON_malloc(numentries*sizeof(char*));if (!entries) return 0;memset(entries,0,numentries*sizeof(char*));/* Retrieve all the results: */child=item->child;while (child && !fail){ret=print_value(child,depth+1,fmt,0);entries[i++]=ret;if (ret) len+=strlen(ret)+2+(fmt?1:0); else fail=1;child=child->next;}/* If we didn't fail, try to malloc the output string */if (!fail)	out=(char*)cJSON_malloc(len);/* If that fails, we fail. */if (!out) fail=1;/* Handle failure. */if (fail){for (i=0;i<numentries;i++) if (entries[i]) cJSON_free(entries[i]);cJSON_free(entries);return 0;}/* Compose the output array. */*out='[';ptr=out+1;*ptr=0;for (i=0;i<numentries;i++){tmplen=strlen(entries[i]);memcpy(ptr,entries[i],tmplen);ptr+=tmplen;if (i!=numentries-1) {*ptr++=',';if(fmt)*ptr++=' ';*ptr=0;}cJSON_free(entries[i]);}cJSON_free(entries);*ptr++=']';*ptr++=0;}return out;	
}/* Build an object from the text. */
static const char *parse_object(cJSON *item,const char *value)
{cJSON *child;if (*value!='{')	{ep=value;return 0;}	/* not an object! */item->type=cJSON_Object;value=skip(value+1);if (*value=='}') return value+1;	/* empty array. */item->child=child=cJSON_New_Item();if (!item->child) return 0;value=skip(parse_string(child,skip(value)));if (!value) return 0;child->string=child->valuestring;child->valuestring=0;if (*value!=':') {ep=value;return 0;}	/* fail! */value=skip(parse_value(child,skip(value+1)));	/* skip any spacing, get the value. */if (!value) return 0;while (*value==','){cJSON *new_item;if (!(new_item=cJSON_New_Item()))	return 0; /* memory fail */child->next=new_item;new_item->prev=child;child=new_item;value=skip(parse_string(child,skip(value+1)));if (!value) return 0;child->string=child->valuestring;child->valuestring=0;if (*value!=':') {ep=value;return 0;}	/* fail! */value=skip(parse_value(child,skip(value+1)));	/* skip any spacing, get the value. */if (!value) return 0;}if (*value=='}') return value+1;	/* end of array */ep=value;return 0;	/* malformed. */
}/* Render an object to text. */
static char *print_object(cJSON *item,int depth,int fmt,printbuffer *p)
{char **entries=0,**names=0;char *out=0,*ptr,*ret,*str;int len=7,i=0,j;cJSON *child=item->child;int numentries=0,fail=0;size_t tmplen=0;/* Count the number of entries. */while (child) numentries++,child=child->next;/* Explicitly handle empty object case */if (!numentries){if (p) out=ensure(p,fmt?depth+4:3);else	out=(char*)cJSON_malloc(fmt?depth+4:3);if (!out)	return 0;ptr=out;*ptr++='{';if (fmt) {*ptr++='\n';for (i=0;i<depth-1;i++) *ptr++='\t';}*ptr++='}';*ptr++=0;return out;}if (p){/* Compose the output: */i=p->offset;len=fmt?2:1;	ptr=ensure(p,len+1);	if (!ptr) return 0;*ptr++='{';	if (fmt) *ptr++='\n';	*ptr=0;	p->offset+=len;child=item->child;depth++;while (child){if (fmt){ptr=ensure(p,depth);	if (!ptr) return 0;for (j=0;j<depth;j++) *ptr++='\t';p->offset+=depth;}print_string_ptr(child->string,p);p->offset=update(p);len=fmt?2:1;ptr=ensure(p,len);	if (!ptr) return 0;*ptr++=':';if (fmt) *ptr++='\t';p->offset+=len;print_value(child,depth,fmt,p);p->offset=update(p);len=(fmt?1:0)+(child->next?1:0);ptr=ensure(p,len+1); if (!ptr) return 0;if (child->next) *ptr++=',';if (fmt) *ptr++='\n';*ptr=0;p->offset+=len;child=child->next;}ptr=ensure(p,fmt?(depth+1):2);	 if (!ptr) return 0;if (fmt)	for (i=0;i<depth-1;i++) *ptr++='\t';*ptr++='}';*ptr=0;out=(p->buffer)+i;}else{/* Allocate space for the names and the objects */entries=(char**)cJSON_malloc(numentries*sizeof(char*));if (!entries) return 0;names=(char**)cJSON_malloc(numentries*sizeof(char*));if (!names) {cJSON_free(entries);return 0;}memset(entries,0,sizeof(char*)*numentries);memset(names,0,sizeof(char*)*numentries);/* Collect all the results into our arrays: */child=item->child;depth++;if (fmt) len+=depth;while (child){names[i]=str=print_string_ptr(child->string,0);entries[i++]=ret=print_value(child,depth,fmt,0);if (str && ret) len+=strlen(ret)+strlen(str)+2+(fmt?2+depth:0); else fail=1;child=child->next;}/* Try to allocate the output string */if (!fail)	out=(char*)cJSON_malloc(len);if (!out) fail=1;/* Handle failure */if (fail){for (i=0;i<numentries;i++) {if (names[i]) cJSON_free(names[i]);if (entries[i]) cJSON_free(entries[i]);}cJSON_free(names);cJSON_free(entries);return 0;}/* Compose the output: */*out='{';ptr=out+1;if (fmt)*ptr++='\n';*ptr=0;for (i=0;i<numentries;i++){if (fmt) for (j=0;j<depth;j++) *ptr++='\t';tmplen=strlen(names[i]);memcpy(ptr,names[i],tmplen);ptr+=tmplen;*ptr++=':';if (fmt) *ptr++='\t';strcpy(ptr,entries[i]);ptr+=strlen(entries[i]);if (i!=numentries-1) *ptr++=',';if (fmt) *ptr++='\n';*ptr=0;cJSON_free(names[i]);cJSON_free(entries[i]);}cJSON_free(names);cJSON_free(entries);if (fmt) for (i=0;i<depth-1;i++) *ptr++='\t';*ptr++='}';*ptr++=0;}return out;	
}/* Get Array size/item / object item. */
int    cJSON_GetArraySize(cJSON *array)							{cJSON *c=array->child;int i=0;while(c)i++,c=c->next;return i;}
cJSON *cJSON_GetArrayItem(cJSON *array,int item)				{cJSON *c=array->child;  while (c && item>0) item--,c=c->next; return c;}
cJSON *cJSON_GetObjectItem(cJSON *object,const char *string)	{cJSON *c=object->child; while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;}/* Utility for array list handling. */
static void suffix_object(cJSON *prev,cJSON *item) {prev->next=item;item->prev=prev;}
/* Utility for handling references. */
static cJSON *create_reference(cJSON *item) {cJSON *ref=cJSON_New_Item();if (!ref) return 0;memcpy(ref,item,sizeof(cJSON));ref->string=0;ref->type|=cJSON_IsReference;ref->next=ref->prev=0;return ref;}/* Add item to array/object. */
void   cJSON_AddItemToArray(cJSON *array, cJSON *item)						{cJSON *c=array->child;if (!item) return; if (!c) {array->child=item;} else {while (c && c->next) c=c->next; suffix_object(c,item);}}
void   cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item)	{if (!item) return; if (item->string) cJSON_free(item->string);item->string=cJSON_strdup(string);cJSON_AddItemToArray(object,item);}
void   cJSON_AddItemToObjectCS(cJSON *object,const char *string,cJSON *item)	{if (!item) return; if (!(item->type&cJSON_StringIsConst) && item->string) cJSON_free(item->string);item->string=(char*)string;item->type|=cJSON_StringIsConst;cJSON_AddItemToArray(object,item);}
void	cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item)						{cJSON_AddItemToArray(array,create_reference(item));}
void	cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item)	{cJSON_AddItemToObject(object,string,create_reference(item));}cJSON *cJSON_DetachItemFromArray(cJSON *array,int which)			{cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return 0;if (c->prev) c->prev->next=c->next;if (c->next) c->next->prev=c->prev;if (c==array->child) array->child=c->next;c->prev=c->next=0;return c;}
void   cJSON_DeleteItemFromArray(cJSON *array,int which)			{cJSON_Delete(cJSON_DetachItemFromArray(array,which));}
cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string) {int i=0;cJSON *c=object->child;while (c && cJSON_strcasecmp(c->string,string)) i++,c=c->next;if (c) return cJSON_DetachItemFromArray(object,i);return 0;}
void   cJSON_DeleteItemFromObject(cJSON *object,const char *string) {cJSON_Delete(cJSON_DetachItemFromObject(object,string));}/* Replace array/object items with new ones. */
void   cJSON_InsertItemInArray(cJSON *array,int which,cJSON *newitem)		{cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) {cJSON_AddItemToArray(array,newitem);return;}newitem->next=c;newitem->prev=c->prev;c->prev=newitem;if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;}
void   cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem)		{cJSON *c=array->child;while (c && which>0) c=c->next,which--;if (!c) return;newitem->next=c->next;newitem->prev=c->prev;if (newitem->next) newitem->next->prev=newitem;if (c==array->child) array->child=newitem; else newitem->prev->next=newitem;c->next=c->prev=0;cJSON_Delete(c);}
void   cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem){int i=0;cJSON *c=object->child;while(c && cJSON_strcasecmp(c->string,string))i++,c=c->next;if(c){newitem->string=cJSON_strdup(string);cJSON_ReplaceItemInArray(object,i,newitem);}}/* Create basic types: */
cJSON *cJSON_CreateNull(void)					{cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_NULL;return item;}
cJSON *cJSON_CreateTrue(void)					{cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_True;return item;}
cJSON *cJSON_CreateFalse(void)					{cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_False;return item;}
cJSON *cJSON_CreateBool(int b)					{cJSON *item=cJSON_New_Item();if(item)item->type=b?cJSON_True:cJSON_False;return item;}
cJSON *cJSON_CreateNumber(double num)			{cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_Number;item->valuedouble=num;item->valueint=(int)num;}return item;}
cJSON *cJSON_CreateString(const char *string)	{cJSON *item=cJSON_New_Item();if(item){item->type=cJSON_String;item->valuestring=cJSON_strdup(string);}return item;}
cJSON *cJSON_CreateArray(void)					{cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Array;return item;}
cJSON *cJSON_CreateObject(void)					{cJSON *item=cJSON_New_Item();if(item)item->type=cJSON_Object;return item;}/* Create Arrays: */
cJSON *cJSON_CreateIntArray(const int *numbers,int count)		{int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
cJSON *cJSON_CreateFloatArray(const float *numbers,int count)	{int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
cJSON *cJSON_CreateDoubleArray(const double *numbers,int count)	{int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateNumber(numbers[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}
cJSON *cJSON_CreateStringArray(const char **strings,int count)	{int i;cJSON *n=0,*p=0,*a=cJSON_CreateArray();for(i=0;a && i<count;i++){n=cJSON_CreateString(strings[i]);if(!i)a->child=n;else suffix_object(p,n);p=n;}return a;}/* Duplication */
cJSON *cJSON_Duplicate(cJSON *item,int recurse)
{cJSON *newitem,*cptr,*nptr=0,*newchild;/* Bail on bad ptr */if (!item) return 0;/* Create new item */newitem=cJSON_New_Item();if (!newitem) return 0;/* Copy over all vars */newitem->type=item->type&(~cJSON_IsReference),newitem->valueint=item->valueint,newitem->valuedouble=item->valuedouble;if (item->valuestring)	{newitem->valuestring=cJSON_strdup(item->valuestring);	if (!newitem->valuestring)	{cJSON_Delete(newitem);return 0;}}if (item->string)		{newitem->string=cJSON_strdup(item->string);			if (!newitem->string)		{cJSON_Delete(newitem);return 0;}}/* If non-recursive, then we're done! */if (!recurse) return newitem;/* Walk the ->next chain for the child. */cptr=item->child;while (cptr){newchild=cJSON_Duplicate(cptr,1);		/* Duplicate (with recurse) each item in the ->next chain */if (!newchild) {cJSON_Delete(newitem);return 0;}if (nptr)	{nptr->next=newchild,newchild->prev=nptr;nptr=newchild;}	/* If newitem->child already set, then crosswire ->prev and ->next and move on */else		{newitem->child=newchild;nptr=newchild;}					/* Set newitem->child and move to it */cptr=cptr->next;}return newitem;
}void cJSON_Minify(char *class="tags" href="/JSON.html" title=json>json)
{char *into=class="tags" href="/JSON.html" title=json>json;while (*class="tags" href="/JSON.html" title=json>json){if (*class="tags" href="/JSON.html" title=json>json==' ') class="tags" href="/JSON.html" title=json>json++;else if (*class="tags" href="/JSON.html" title=json>json=='\t') class="tags" href="/JSON.html" title=json>json++;	/* Whitespace characters. */else if (*class="tags" href="/JSON.html" title=json>json=='\r') class="tags" href="/JSON.html" title=json>json++;else if (*class="tags" href="/JSON.html" title=json>json=='\n') class="tags" href="/JSON.html" title=json>json++;else if (*class="tags" href="/JSON.html" title=json>json=='/' && class="tags" href="/JSON.html" title=json>json[1]=='/')  while (*class="tags" href="/JSON.html" title=json>json && *class="tags" href="/JSON.html" title=json>json!='\n') class="tags" href="/JSON.html" title=json>json++;	/* double-slash comments, to end of line. */else if (*class="tags" href="/JSON.html" title=json>json=='/' && class="tags" href="/JSON.html" title=json>json[1]=='*') {while (*class="tags" href="/JSON.html" title=json>json && !(*class="tags" href="/JSON.html" title=json>json=='*' && class="tags" href="/JSON.html" title=json>json[1]=='/')) class="tags" href="/JSON.html" title=json>json++;class="tags" href="/JSON.html" title=json>json+=2;}	/* multiline comments. */else if (*class="tags" href="/JSON.html" title=json>json=='\"'){*into++=*class="tags" href="/JSON.html" title=json>json++;while (*class="tags" href="/JSON.html" title=json>json && *class="tags" href="/JSON.html" title=json>json!='\"'){if (*class="tags" href="/JSON.html" title=json>json=='\\') *into++=*class="tags" href="/JSON.html" title=json>json++;*into++=*class="tags" href="/JSON.html" title=json>json++;}*into++=*class="tags" href="/JSON.html" title=json>json++;} /* string literals, which are \" sensitive. */else *into++=*class="tags" href="/JSON.html" title=json>json++;			/* All other characters. */}*into=0;	/* and null-terminate. */
}
code>

        cJSON.h 

<code class="language-cpp">/*Copyright (c) 2009 Dave GamblePermission is hereby granted, free of charge, to any person obtaining a copyof this software and associated documentation files (the "Software"), to dealin the Software without restriction, including without limitation the rightsto use, copy, modify, merge, publish, distribute, sublicense, and/or sellcopies of the Software, and to permit persons to whom the Software isfurnished to do so, subject to the following conditions:The above copyright notice and this permission notice shall be included inall copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ORIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THEAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHERLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS INTHE SOFTWARE.
*/#ifndef cJSON__h
#define cJSON__h#ifdef __cplusplus
extern "C"
{
#endif/* 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#define cJSON_IsReference 256
#define cJSON_StringIsConst 512/* The cJSON structure: */
typedef struct cJSON {struct cJSON *next,*prev;	/* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */struct cJSON *child;		/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */int type;					/* The type of the item, as above. */char *valuestring;			/* The item's string, if type==cJSON_String */int valueint;				/* The item's number, if type==cJSON_Number */double valuedouble;			/* The item's number, if type==cJSON_Number */char *string;				/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
} cJSON;typedef struct cJSON_Hooks {void *(*malloc_fn)(size_t sz);void (*free_fn)(void *ptr);
} cJSON_Hooks;/* Supply malloc, realloc and free functions to cJSON */
extern void cJSON_InitHooks(cJSON_Hooks* hooks);/* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */
extern cJSON *cJSON_Parse(const char *value);
/* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */
extern char  *cJSON_Print(cJSON *item);
/* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */
extern char  *cJSON_PrintUnformatted(cJSON *item);
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
extern char *cJSON_PrintBuffered(cJSON *item,int prebuffer,int fmt);
/* Delete a cJSON entity and all subentities. */
extern void   cJSON_Delete(cJSON *c);/* Returns the number of items in an array (or object). */
extern int	  cJSON_GetArraySize(cJSON *array);
/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
extern cJSON *cJSON_GetArrayItem(cJSON *array,int item);
/* Get item "string" from object. Case insensitive. */
extern cJSON *cJSON_GetObjectItem(cJSON *object,const char *string);/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
extern const char *cJSON_GetErrorPtr(void);/* These calls create a cJSON item of the appropriate type. */
extern cJSON *cJSON_CreateNull(void);
extern cJSON *cJSON_CreateTrue(void);
extern cJSON *cJSON_CreateFalse(void);
extern cJSON *cJSON_CreateBool(int b);
extern cJSON *cJSON_CreateNumber(double num);
extern cJSON *cJSON_CreateString(const char *string);
extern cJSON *cJSON_CreateArray(void);
extern cJSON *cJSON_CreateObject(void);/* These utilities create an Array of count items. */
extern cJSON *cJSON_CreateIntArray(const int *numbers,int count);
extern cJSON *cJSON_CreateFloatArray(const float *numbers,int count);
extern cJSON *cJSON_CreateDoubleArray(const double *numbers,int count);
extern cJSON *cJSON_CreateStringArray(const char **strings,int count);/* Append item to the specified array/object. */
extern void cJSON_AddItemToArray(cJSON *array, cJSON *item);
extern void	cJSON_AddItemToObject(cJSON *object,const char *string,cJSON *item);
extern void	cJSON_AddItemToObjectCS(cJSON *object,const char *string,cJSON *item);	/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object */
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
extern void cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
extern void	cJSON_AddItemReferenceToObject(cJSON *object,const char *string,cJSON *item);/* Remove/Detatch items from Arrays/Objects. */
extern cJSON *cJSON_DetachItemFromArray(cJSON *array,int which);
extern void   cJSON_DeleteItemFromArray(cJSON *array,int which);
extern cJSON *cJSON_DetachItemFromObject(cJSON *object,const char *string);
extern void   cJSON_DeleteItemFromObject(cJSON *object,const char *string);/* Update array items. */
extern void cJSON_InsertItemInArray(cJSON *array,int which,cJSON *newitem);	/* Shifts pre-existing items to the right. */
extern void cJSON_ReplaceItemInArray(cJSON *array,int which,cJSON *newitem);
extern void cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);/* Duplicate a cJSON item */
extern cJSON *cJSON_Duplicate(cJSON *item,int recurse);
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
need to be released. With recurse!=0, it will duplicate any children connected to the item.
The item->next and ->prev pointers are always zero on return from Duplicate. *//* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
extern cJSON *cJSON_ParseWithOpts(const char *value,const char **return_parse_end,int require_null_terminated);extern void cJSON_Minify(char *class="tags" href="/JSON.html" title=json>json);/* Macros for creating things quickly. */
#define cJSON_AddNullToObject(object,name)		cJSON_AddItemToObject(object, name, cJSON_CreateNull())
#define cJSON_AddTrueToObject(object,name)		cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
#define cJSON_AddFalseToObject(object,name)		cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
#define cJSON_AddBoolToObject(object,name,b)	cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
#define cJSON_AddNumberToObject(object,name,n)	cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
#define cJSON_AddStringToObject(object,name,s)	cJSON_AddItemToObject(object, name, cJSON_CreateString(s))/* When assigning an integer value, it needs to be propagated to valuedouble too. */
#define cJSON_SetIntValue(object,val)			((object)?(object)->valueint=(object)->valuedouble=(val):(val))
#define cJSON_SetNumberValue(object,val)		((object)?(object)->valueint=(object)->valuedouble=(val):(val))#ifdef __cplusplus
}
#endif#endif
code>

        使用方法:

        就按照创建一个点亮LED灯工程那样࿰c;新建源文件和头文件࿰c;把这两段代码直接复制进去即可正常调用

七、工程源码

        下面这篇文章中是一个未使用cJSON构建的࿰c;大家下载下来后可以按照上述步骤操作一下࿰c;毕竟实践才是检验真理的唯一标准࿰c;需要构建完成的࿰c;也可以后台私信我        

class="link-card-box">class="link-title">STM32+ESP8266+MQTT协议连接阿里云实现温湿度上传class="link-link">class="link-link-icon" src="https://csdnimg.cn/release/blog_editor_html/release2.3.7/ckeditor/plugins/CsdnLink/icons/icon-default.png?t=O83A" alt="icon-default.png?t=O83A" />https://mp.csdn.net/mp_blog/creation/editor/141951792


http://www.ppmy.cn/server/118057.html

相关文章

【SSRF漏洞】——gopherus工具伪造

改变的确很难&#xff0c;但结果值得冒险 本文如有错误之处&#xff0c;还请各位师傅指正 目录 一.gopherus概述 二.gopherus安装使用 三.gopherus覆盖的服务 四.使用案例 web359&#xff1a; web360&#xff1a; 一.gopherus概述 Gopherus是一个专为生成Gopher协议Payloa…

科技与艺术完美融合的LED异形创意圆形(饼/盘)显示屏横空出世

随着LED技术的飞速发展&#xff0c;这款集科技与艺术于一体的异形创意圆形&#xff08;饼/盘&#xff09;显示屏&#xff0c;不仅以其独特的形态打破了传统显示屏的界限&#xff0c;更在视觉呈现上开启了前所未有的新篇章。它不再仅仅是信息传递的载体&#xff0c;而是成为了空…

WPF入门教学二 安装与配置WPF开发环境

在安装与配置WPF&#xff08;Windows Presentation Foundation&#xff09;开发环境时&#xff0c;您需要遵循一系列步骤来确保一切顺利进行。WPF是微软提供的一个强大的UI框架&#xff0c;用于构建Windows桌面应用程序。以下是详细的安装与配置指南&#xff1a; 安装Visual S…

JavaScript和jQuery的区别

JavaScript和jQuery都是用于网页开发的脚本语言&#xff0c;但它们之间存在一些重要的区别。 基础与库&#xff1a;JavaScript是一种编程语言&#xff0c;它是Web开发的基础&#xff0c;被所有的现代浏览器所支持。而jQuery是一个JavaScript库&#xff0c;它简化了HTML文档遍历…

react 基础语法

前置知识 类的回顾 通过class关键字定义一个类 类名首字母大写 class类有constructor构造器 new 一个类得到一个实例 类还有方法&#xff0c;该方法也会在其原型上 static静态数据&#xff0c;访问静态属性通过 类名.id getter和setter getter&#xff1a;定义一个属性&…

计算机网络通关学习(一)

简介 之前我通过王道的考研课进行了计算机网络的学习&#xff0c;但是在秋招准备过程中发现之前的笔记很多不足&#xff0c;学习的知识不够深入和巩固&#xff0c;所以再重新对《图解HTTP》&《图解TCP/IP》进行深度学习后&#xff0c;总结出了此篇博客&#xff0c;由于内容…

解码 OpenAI 的 o1 系列大型语言模型

OpenAI 表示&#xff0c;其 Strawberry 项目已升级为新的大型语言模型 (LLM) 系列&#xff0c;公司将其命名为 OpenAI o1。 该公司表示&#xff0c;新系列模型还包括一个 o1-mini 版本&#xff0c;以提高成本效益&#xff0c;可根据其推理能力与最新的GPT-4o 模型进行区分。 …

Docker | 轻松管理容器:Portainer安装与使用指南

引言 在Docker的世界中&#xff0c;管理容器、镜像、网络和卷可能会变得复杂&#xff0c;特别是当项目规模扩大时。幸运的是&#xff0c;Portainer提供了一个简单而强大的可视化界面来管理Docker环境。本文将带你了解如何安装和使用Portainer&#xff0c;让你的容器管理变得更…

Linux5-echo,>,tail

1.echo命令 echo是输出命令&#xff0c;类似printf 例如&#xff1a;echo "hello world"&#xff0c;输出hello world echo pwd&#xff0c;输出pwd的位置。是键盘上~ 2.重定向符> >> >指把左边内容覆盖到右边 echo hello world>test.txt >…

JS设计模式之外观模式:简化复杂系统调用的利器

一、了解外观模式 概念 外观模式&#xff08;Facade Pattern&#xff09;是一种结构型设计模式&#xff0c;它提供了一个简单的接口&#xff0c;隐藏了一个复杂系统的内部复杂性&#xff0c;使得客户端可以通过该接口与系统进行交互&#xff0c;而无需了解系统内部的具体实现…

人工智能——猴子摘香蕉问题

一、实验目的 求解猴子摘香蕉问题&#xff0c;根据猴子不同的位置&#xff0c;求解猴子的移动范围&#xff0c;求解对应的过程&#xff0c;针对不同的目标状态进行求解。 二、实验内容 根据场景有猴子、箱子、香蕉&#xff0c;香蕉挂天花板上。定义多种谓词描述位置、状态等…

快速开发与维护:探索 AndroidAnnotations

在移动应用开发的世界中&#xff0c;效率和可维护性是两个至关重要的要素。随着应用功能的不断增长和用户需求的不断变化&#xff0c;开发者们一直在寻找能够提高生产力的工具和框架。今天&#xff0c;我们将深入探讨一个能够帮助开发者实现快速开发和易于维护的框架——Androi…

linux gcc 静态库的简单介绍

在 Linux 上&#xff0c;使用 GCC 编译器来创建和调用静态库时&#xff0c;涉及的实现原理和调用机制可以分为以下几个步骤&#xff1a; 1. 静态库的创建 静态库&#xff08;通常以 .a 结尾&#xff09;是由多个目标文件&#xff08;.o 文件&#xff09;打包在一起的归档文件…

Transformer模型详细步骤

Transformer模型是nlp任务中不能绕开的学习任务&#xff0c;我将从数据开始&#xff0c;每一步骤都列举出来&#xff0c;然后对应重点的代码进行讲解 ------------------------------------------------------------------------------------------------------------- Trans…

黑马程序员-JavaScrip-day01

文章目录 JavaScript简介和体验01-JS书写位置02-JS注释和结束符03-JS输入输出04-变量的声明与复制05-变量的更新以及输入用户名案例06-交换变量07-变量的本质和命名规则08-数组的基本使用09-常量10-数字数据类型和算数运算符11-字符串类型12-模板字符串13-bool、null、undefine…

大众萨克森:SNP助力汽车制造智能化,实现SAP S/4HANA系统成功升级

关于大众萨克森 VW Sachsen 大众汽车&#xff08;Volkswagen Sachsen GmbH&#xff09;包括位于德国茨维考的汽车工厂、位于德累斯顿的透明工厂和位于开姆尼茨的发动机工厂。茨维考汽车厂拥有 7,900名员工&#xff0c;每天生产1,350辆高尔夫和帕萨特汽车。在开姆尼茨的发动机工…

requests-html的详细使用方法

requests-html是一个Python库&#xff0c;用于发送HTTP请求并解析HTML。它基于 requests 和 pyquery 库&#xff0c;提供了一种更简单和更方便的方式来获取和处理网页内容。 下面是requests-html的一些常用使用方法&#xff1a; 安装requests-html库&#xff1a; pip instal…

【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)

&#x1f31f;&#x1f31f;作者主页&#xff1a;ephemerals__ &#x1f31f;&#x1f31f;所属专栏&#xff1a;C 目录 前言 一、取地址运算符重载 1. const修饰成员函数 2. 取地址运算符重载 二、深究构造函数 三、类型转换 四、static修饰成员 1. static修饰成员变…

Linux 入门:简单的基础操作

“批判他人总是想的太简单 剖析自己总是想的太困难” 文章目录 前言Linux 入门&#xff1a;从基础操作到 WSL2 安装文章有误敬请斧正 不胜感恩&#xff01;1. 什么是 Linux&#xff1f;2. Linux 和其他系统有啥不同&#xff1f;3. Linux 的主要组成4. 常见 Linux 发行版5. 基本…

云计算和虚拟化技术 背诵

https://zhuanlan.zhihu.com/p/612215164 https://zhuanlan.zhihu.com/p/612215164 云计算是指把计算资源、存储资源、网络资源、应用软件等集合起来&#xff0c;采用虚拟化技术 &#xff0c;将这些资源池化&#xff0c;组成资源共享池&#xff0c;共享池即是“云”。 云计算…