当前位置: 首页 > news >正文

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

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

一、简介

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

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

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

二、解决的问题

        1、问题阐述

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

图-1 

图-2

         sprintf基本用法及示例:

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

        示例:

#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;
}

三、cJSON构建传输字符串 

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

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

2、详细讲解

        第一步:

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

        第二步:

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

        第三步:

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

         第四步:

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

        第五步:

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

        第六步:

        一定要将“ JSON “对象和存储无格式字符串用的指针 str 清空,要不然会造成占用内存导致卡机

四、相关函数详解 

①、cJSON_CreateObject()

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

        具体用法如下:

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

  1. cJSON_AddNullToObject(object, name)

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

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

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

    • 作用:向 JSON 对象中添加一个布尔值,可以是 true 或 false
    • 参数
      • object:指向 cJSON 结构体的指针,表示要添加布尔值的目标 JSON 对象。
      • name:键名(字符串),表示布尔值对应的键。
      • b:布尔值,可以是 true 或 false(通常为 1 或 0)。
  5. cJSON_AddNumberToObject(object, name, n)

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

    • 作用:向 JSON 对象中添加一个字符串值。
    • 参数
      • object:指向 cJSON 结构体的指针,表示要添加字符串值的目标 JSON 对象。
      • name:键名(字符串),表示字符串值对应的键。
      • s:字符串值(通常是 char * 类型),表示要添加的字符串。

        具体应用:

#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 *json = cJSON_CreateObject();// 向 JSON 对象中添加不同类型的值cJSON_AddStringToObject(json, "name", "Alice");cJSON_AddNumberToObject(json, "age", 25);cJSON_AddBoolToObject(json, "is_student", 1);cJSON_AddNullToObject(json, "job");cJSON_AddTrueToObject(json, "is_active");cJSON_AddFalseToObject(json, "is_admin");// 打印 JSON 对象Serial_Printf("%s\n", cJSON_Print(json));// 清理内存cJSON_Delete(json);Delay_ms(100);}}

        结果显示: 

③、cJSON_PrintUnformatted()

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

        具体用法:

④、free、cJSON_Delete()

        free是 C 标准库中的一个函数,用于释放之前通过 malloccallocrealloc 动态分配的内存块。

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

        具体用法:

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

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

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

        ①、找到后缀为 .s 的这个文件,这是单片机的启动文件

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

六、cJSON源码

         cJSON.c

/*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 *json)
{char *into=json;while (*json){if (*json==' ') json++;else if (*json=='\t') json++;	/* Whitespace characters. */else if (*json=='\r') json++;else if (*json=='\n') json++;else if (*json=='/' && json[1]=='/')  while (*json && *json!='\n') json++;	/* double-slash comments, to end of line. */else if (*json=='/' && json[1]=='*') {while (*json && !(*json=='*' && json[1]=='/')) json++;json+=2;}	/* multiline comments. */else if (*json=='\"'){*into++=*json++;while (*json && *json!='\"'){if (*json=='\\') *into++=*json++;*into++=*json++;}*into++=*json++;} /* string literals, which are \" sensitive. */else *into++=*json++;			/* All other characters. */}*into=0;	/* and null-terminate. */
}

        cJSON.h 

/*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 *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

        使用方法:

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

七、工程源码

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

STM32+ESP8266+MQTT协议连接阿里云实现温湿度上传icon-default.png?t=O83Ahttps://mp.csdn.net/mp_blog/creation/editor/141951792

相关文章:

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

编写方向&#xff1a;本人就不泛泛的编写一篇什么一文学会cJSON了&#xff0c;没什么突出点&#xff0c;也就我水水字数&#xff0c;你们看来看去也不懂&#xff0c;本人是从上阿里云传信息接触的cJSON的&#xff0c;我就此写一篇针对性的文章&#xff0c;希望对大家有用&#…...

【Git】Clone

当git clone失败时&#xff0c;出现 RPC failed; curl 92 HTTP/2 stream 0 was not closed cleanly: CANCEL (err 8) 错误&#xff0c;可能由于网络连接不稳定或仓库太大导致的。 可以尝试以下几种方法来解决这个问题&#xff1a; 增加 Git 的缓冲区大小&#xff1a; git confi…...

web开发 之 HTML、CSS、JavaScript、以及JavaScript的高级框架Vue(学习版2)

一、前言 接下来就是来解决这些问题 二、 Ajax 1.ajax javscript是网页三剑客之一&#xff0c;空用来控制网页的行为的 xml是一种标记语言&#xff0c;是用来存储数据的 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-…...

【课程学习】信号检测与估计II

b站 文章目录 1-概述 1-概述 线性、正交、平稳、高斯 研究线性模型&#xff0c;采用正交化方法&#xff0c;假设信号平稳&#xff0c;考虑信号的统计特性是高斯的。 本学期考虑&#xff0c;非线性、非正交、非平稳、非高斯。 阵列处理 1980-1990 MUSIC 稀疏性 2006-2012 LASS 时…...

【深度学习|PyTorch】基于 PyTorch 搭建 U-Net 深度学习语义分割模型——附代码及其解释!

【深度学习|PyTorch】基于 PyTorch 搭建 U-Net 深度学习语义分割模型——附代码及其解释&#xff01; 【深度学习|PyTorch】基于 PyTorch 搭建 U-Net 深度学习语义分割模型——附代码及其解释&#xff01; 论文地址&#xff1a; https://arxiv.org/abs/1505.04597 代码地址&a…...

DPDK基础入门(十):虚拟化

I/O虚拟化 全虚拟化&#xff1a;宿主机截获客户机对I/O设备的访问请求&#xff0c;然后通过软件模拟真实的硬件。这种方式对客户机而言非常透明&#xff0c;无需考虑底层硬件的情况&#xff0c;不需要修改操作系统。 半虚拟化&#xff1a;通过前端驱动/后端驱动模拟实现I/O虚拟…...

OpenCV_图像旋转超详细讲解

图像转置 transpose(src, dst); transpose()可以实现像素下标的x和y轴坐标进行对调&#xff1a;dst(i,j)src(j,i)&#xff0c;接口形式 transpose(InputArray src, // 输入图像OutputArray dst, // 输出 ) 图像翻转 flip(src, dst, 1); flip()函数可以实现对图像的水平翻转…...

关于 OceanBase 4.x 中被truncate的 table 不再支持进回收站的原因

近期&#xff0c;OceanBase的问答社区中收到了不少用户的询问&#xff0c;关于OceanBase 3.x版本支持被truncate的table进入回收站的功能&#xff0c;为何在升级到4.x版本后不再支持了&#xff1f;为了解答大家的疑惑&#xff0c;我们将通过这篇文章来浅析 OceanBase在4.x版本中…...

Numpy索引详解(数值索引,列表索引,布尔索引)

数值索引 数值索引类似列表索引操作使用[]&#xff0c;参数为下标&#xff0c;[0,len-1),高维数组的索引使用多个[]连用分别代表一维索引&#xff0c;二维索引... import numpy as np import torchnp.random.seed(1) data1 np.arange(5) data2 np.arange(15).reshape(3,5) …...

大数据新视界 --大数据大厂之MongoDB与大数据:灵活文档数据库的应用场景

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…...

三年 Sparker 都不一定知道的算子内幕

一、如何在 mapPartitions 中释放资源 mapPartitions是一种对每个分区进行操作的转换操作&#xff0c;于常用的map操作类似&#xff0c;但它处理的是整个分区而不是单个元素。mapPartitions的应用场景适合处理需要在每个分区内批量处理数据的场景&#xff0c;通常用于优化性能…...

PG表空间

目录标题 PG表空间PostgreSQL表空间的最佳实践是什么&#xff1f;如何在PostgreSQL中创建和管理自定义表空间&#xff1f;PostgreSQL表空间对数据库性能的具体影响有哪些&#xff1f;在PostgreSQL中&#xff0c;如何迁移数据到不同的表空间以优化存储布局&#xff1f;PostgreSQ…...

谷粒商城のElasticsearch

文章目录 前言一、前置知识1、Elasticsearch 的结构2、倒排索引 (Inverted Index)2.1、 索引阶段2.2、查询阶段 二、环境准备1、安装Es2、安装Kibana3、安装 ik 分词器 三、项目整合1、引入依赖2、整合业务2.1、创建索引、文档、构建查询语句2.2、整合业务代码 后记 前言 本篇介…...

排队免单模式小程序开发

开发一个排队免单模式的小程序涉及多个方面&#xff0c;包括需求分析、界面设计、后端开发、数据库设计以及测试上线等。下面我将详细介绍每个步骤的概要&#xff1a; 1.需求分析 明确目标&#xff1a;首先确定小程序的核心功能&#xff0c;即排队免单模式的具体实现方式。例如…...

从OracleCloudWorld和财报看Oracle的转变

2024年9月9-12日Oracle Cloud World在美国拉斯维加斯盛大开幕 押注AI和云 Oracle 创始人Larry Ellison做了对Oracle战略和未来愿景的主旨演讲&#xff0c;在演讲中Larry将AI技术和云战略推到了前所未有的高度&#xff0c;从新的Oracle 23c改名到Oracle23ai&#xff0c;到Oracl…...

搭建 PHP

快速搭建 PHP 环境指南 PHP 是一种广泛用于 Web 开发的后端脚本语言&#xff0c;因其灵活性和易用性而受到开发者的青睐。无论是开发个人项目还是企业级应用&#xff0c;PHP 环境的搭建都是一个不可忽视的基础步骤。本指南将带您快速学习如何在不同平台上搭建 PHP 环境&#x…...

kubernetes技术详解,带你深入了解k8s

目录 一、Kubernetes简介 1.1 容器编排应用 1.2 Kubernetes简介 1.3 k8s的设计架构 1.3.1 k8s各个组件的用途 1.3.2 k8s各组件之间的调用关系 1.3.3 k8s的常用名词概念 1.3.4 k8s的分层结构 二、k8s集群环境搭建 2.1 k8s中容器的管理方式 2.2 k8s环境部署 2.2.1 禁用…...

Gateway学习笔记

目录 介绍&#xff1a; 核心概念 依赖 路由 断言 基本的断言工厂 自定义断言 过滤器 路由过滤器 过滤器工厂 自定义路由过滤器 全局过滤器 其他 过滤器执行顺序 前置后置&#xff08;&#xff1f;&#xff09; 跨域问题 yaml 解决 配置类解决 介绍&#x…...

创造增强叙事的互动:Allison Crank的沉浸式体验设计理念

在沉浸式技术日新月异的今天,如何通过用户交互增强叙事,而非分散注意力,成为了设计师们共同面临的挑战。作为用户体验设计师和研究员,Allison Crank以其独特的视角和丰富的经验,为我们揭示了这一领域的核心原则与实践方法。 叙事与互动的和谐共生 Allison Crank强调,互…...

Requests-HTML模块怎样安装和使用?

要安装和使用Requests-HTML模块&#xff0c;您可以按照以下步骤进行操作&#xff1a; 打开命令行界面&#xff08;如Windows的命令提示符或Mac的终端&#xff09;。 使用pip命令安装Requests-HTML模块。在命令行中输入以下命令并按回车键执行&#xff1a; pip install request…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

通过Wrangler CLI在worker中创建数据库和表

官方使用文档&#xff1a;Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后&#xff0c;会在本地和远程创建数据库&#xff1a; npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库&#xff1a; 现在&#xff0c;您的Cloudfla…...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

蓝桥杯 2024 15届国赛 A组 儿童节快乐

P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡&#xff0c;轻快的音乐在耳边持续回荡&#xff0c;小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下&#xff0c;六一来了。 今天是六一儿童节&#xff0c;小蓝老师为了让大家在节…...

条件运算符

C中的三目运算符&#xff08;也称条件运算符&#xff0c;英文&#xff1a;ternary operator&#xff09;是一种简洁的条件选择语句&#xff0c;语法如下&#xff1a; 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true&#xff0c;则整个表达式的结果为“表达式1”…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现

摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序&#xff0c;以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务&#xff0c;提供稳定高效的数据处理与业务逻辑支持&#xff1b;利用 uniapp 实现跨平台前…...

Spring Boot面试题精选汇总

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...