JSON数据格式讲解与cJSON库的使用

文章目录

  • 写在前面
  • 一、安装cJSON
  • 二、使用cJSON
    • 1、使用的文件
    • 2、如何传输数据:****
  • 三、JSON语法
  • 四、cJSON函数讲解
    • 1、cJSON结构体 **
    • 2、cJSON结构体与字符串之间的转换(重要)
      • 2.1、标题将cJSON结构体转换为字符串(常用)
      • 2.2、将字符串转为cJSON结构体(常用)
    • 3、cJSON创建键值对
      • 3.1、先调用 cJSON_CreateXXX 创建对象或数组,然后调用 cJSON_AddItemToObject 将值加入到对象或数组中
      • 3.2、直接调用 cJSON_AddXXXToObject 创建并添加值到对象中
    • 4、解析
    • 5、释放cJSON数据
  • 五、示例
    • 1、创建
    • 2、解析(主要参考与使用)
      • 2.1、解析 {}
      • 2.2、解析[ {} {} ]
    • 3、解析(参考形式)
      • 3.1、解析 {}
      • 3.2、解析 [ ]
      • 3.3、解析 [ {} {} ]
      • 3.4、解析[ [ ] [ ] ]
      • 3.5、解析 { { } { } }
    • 参考文章

写在前面

什么是JSON:一种轻量级的数据交换格式
JSON用途:解析收到的数据和发送对方能够解析的数据
什么是cJSON:c语言格式下使用JSON的工具

一、安装cJSON

cjson官方库,直接点击下载zip,解压缩

git clone https://github.com/DaveGamble/cJSON.git
cd cJSON/
mkdir build
cd build/
cmake ..
make
make install

二、使用cJSON

1、使用的文件

然后我们,可以看到很多文件,但是,我们不需要这么多,使用cjson只需要两个文件,
拷贝cJSON.c和cJSON.h文件到自己的项目中就可以了,linux,windows上都可以使用

CJOSN.h
CJSON.c

2、如何传输数据:****

1、创建cJSON格式数据,转换成为cJSON字符串,然后传输。
2、将cJSON字符串解析成cJSON格式数据,然后提取出相应的数据内容。

三、JSON语法

JSON对象是一个无序的"key(关键字)/value(值)"键值对的集合:
"{“开始,以”}“结束 ,允许嵌套使用
每个key(关键字)和value(值)成对出现,关键字和值之间使用”:“分隔
键/值之间用”,"分隔
在这些字符前后允许存在无意义的空白符

其中**关键字**只能是字符串(使用双引号“”表示)****可以有如下表示:数字(整数或浮点数)字符串(在双引号中)逻辑值(true 或 false)数组 (在中括号中)对象 (在大括号中)null

四、cJSON函数讲解

1、cJSON结构体 **

/* The cJSON structure: */
typedef struct cJSON
{
//这些不用管struct cJSON *next;struct cJSON *prev;struct cJSON *child;//这些都要知道//该json对象的类型,可以是字符串,int,double....int type;/* The item's string, if type==cJSON_String  and type == cJSON_Raw *///如果类型是字符串,那么键值的字符串的值存在这里char *valuestring;/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead *///如果类型是int,那么值存在这里int valueint;/* The item's number, if type==cJSON_Number *///如果类型是double,那么值存在这里double valuedouble;/* The item's name string, if this item is the child of, or is in the list of subitems of an object. *///存放名字的地方char *string;
} cJSON;

2、cJSON结构体与字符串之间的转换(重要)

2.1、标题将cJSON结构体转换为字符串(常用)

使用这个两个函数一定一定一定要 调用cJSON_Delete函数 释放它们返回的指针内存

//将CJSON数据转换为字符串(保留原来的格式:例如会保留空格和回车)
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
//将CJSON数据转换为字符串(删除所有格式,只保留文本)
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);

2.2、将字符串转为cJSON结构体(常用)

//将json字符串转换为结构体,并且将其赋给一个指针
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);

3、cJSON创建键值对

3.1、先调用 cJSON_CreateXXX 创建对象或数组,然后调用 cJSON_AddItemToObject 将值加入到对象或数组中

CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);	//创建对象---常用
CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);	//创建数组---常用
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);//创建整型数组
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);//创建双浮点型数组CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);	//在对象中添加项目
CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item);//在数组中添加项目

3.2、直接调用 cJSON_AddXXXToObject 创建并添加值到对象中

CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean);
CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number);
CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string);
CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw);
CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name);
CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name);

4、解析

注意:解析—是从cJSON结构体类型中—解析

//获取数组大小
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
//获取数组里面的某一个值
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
//这个函数将某一个键值对,提取出来放到一个结构体中
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string)

5、释放cJSON数据

void  cJSON_Delete(cJSON *c);
/*作用:释放位于堆中cJSON结构体内存

五、示例

1、创建

#include <stdio.h>
#include "cJSON.h"int main(void)
{double  grade[4]={66.51,118.52,61.53,128.54};int		time[4]={123,456,789,150};cJSON *TCP = cJSON_CreateObject();				//创建一个对象cJSON_AddStringToObject(TCP,"name","MQ");		//添加字符串 cJSON_AddNumberToObject(TCP,"age",25);	    	//添加整型数字 cJSON_AddNumberToObject(TCP,"height",183.52);	//添加浮点型数字cJSON_AddFalseToObject(TCP,"gender");			//添加逻辑值falsecJSON *ADD	= cJSON_CreateObject();				//创建一个对象cJSON_AddStringToObject(ADD,"country","China");	//添加字符串 cJSON_AddNumberToObject(ADD,"zip-code",123456);	//添加整型数字cJSON_AddItemToObject(TCP,"address",ADD);cJSON *SUB  = cJSON_CreateArray();				//创建一个数组cJSON_AddStringToObject(SUB,"","政治"); 		//添加字符串到数组cJSON_AddStringToObject(SUB,"","数学");cJSON_AddStringToObject(SUB,"","英语");cJSON_AddStringToObject(SUB,"","专业课");cJSON_AddItemToObject(TCP,"subject",SUB);		//添加数组到对象cJSON *TIM  = cJSON_CreateIntArray(time,4);		//创建一个整型数组cJSON_AddItemToObject(TCP,"time",TIM);cJSON *GRA  = cJSON_CreateDoubleArray(grade,4);	//创建一个双浮点型数组cJSON_AddItemToObject(TCP,"grade",GRA);cJSON *STU  = cJSON_CreateArray();			//创建一个数组cJSON *Z3  = cJSON_CreateObject();			//创建一个对象cJSON_AddStringToObject(Z3,"name","张三");	//添加字符串 cJSON_AddNumberToObject(Z3,"age",24);	    //添加整型数字 cJSON_AddTrueToObject(Z3,"gender");			//添加逻辑值 cJSON_AddItemToArray(STU,Z3);				//添加对象到数组中 cJSON *L4  = cJSON_CreateObject();			//创建一个对象cJSON_AddStringToObject(L4,"name","李四");	//添加字符串 cJSON_AddNumberToObject(L4,"age",25);	    //添加整型数字 cJSON_AddTrueToObject(L4,"gender");			//添加逻辑值 cJSON_AddItemToArray(STU,L4);				//添加对象到数组中cJSON *W5  = cJSON_CreateObject();			//创建一个对象cJSON_AddStringToObject(W5,"name","王五");	//添加字符串 cJSON_AddNumberToObject(W5,"age",26);	    //添加整型数字 cJSON_AddTrueToObject(W5,"gender");			//添加逻辑值 cJSON_AddItemToArray(STU,W5);				//添加对象到数组中cJSON_AddItemToObject(TCP,"student",STU);	//添加数组到对象中char *json_data = cJSON_Print(TCP);	//JSON数据结构转换为JSON字符串printf("%s\n",json_data);//输出字符串cJSON_Delete(TCP);//清除结构体return 0;
}

现象

{"name":	"MQ","age":	25,"height":	183.52,"gender":	false,"address":	{"country":	"China","zip-code":	123456},"subject":	["政治", "数学", "英语", "专业课"],"time":	[123, 456, 789, 150],"grade":	[66.51, 118.52, 61.53, 128.54],"student":	[{"name":	"张三","age":	24,"gender":	true}, {"name":	"李四","age":	25,"gender":	true}, {"name":	"王五","age":	26,"gender":	true}]
}

2、解析(主要参考与使用)

2.1、解析 {}

int parsecjson_data(char *jsonstring)
{	cJSON *cjson= cJSON_Parse(jsonstring);if(cjson) {//解析 JSON 数据并处理cJSON *state = cJSON_GetObjectItem(cjson, "state");if (state != NULL && cJSON_IsString(state)) {printf("State: %s\n", state->valuestring);		//字符串}cJSON *brightness = cJSON_GetObjectItem(cjson, "brightness");if (brightness != NULL && cJSON_IsNumber(brightness)) {printf("Brightness: %d\n", brightness->valueint);		//整形}cJSON *height = cJSON_GetObjectItem(object2, "height");  if (height != NULL && cJSON_IsNumber(height)) {printf("height: %d \n", height->valuedouble);			//浮点型}cJSON *gender = cJSON_GetObjectItem(object2, "gender");  if (gender != NULL && cJSON_IsBool(gender)) {printf("gender: %d \n", gender->type);			//布尔类型	true/false}}cJSON_Delete(cjson);return 0;
}

2.2、解析[ {} {} ]

int parsecjson_data(char *jsonstring)
{	cJSON *cjson = cJSON_Parse(jsonstring);if (cjson != NULL && cJSON_IsArray(cjson)) {int array_size = cJSON_GetArraySize(cjson);if (array_size >= 2) {cJSON *object1 = cJSON_GetArrayItem(cjson, 0);  // 获取数组中的第一个对象cJSON *object2 = cJSON_GetArrayItem(cjson, 1);  // 获取数组中的第二个对象if (object1 != NULL && cJSON_IsObject(object1)) {		// 第一个对象中的字段cJSON *sens1 = cJSON_GetObjectItem(object2, "K3");  // 第一个对象中有名为 K3 的字段if (sens1 != NULL && cJSON_IsNumber(sens1)) {car.sens1 = sens1->valueint;printf("sens1: %d \n", sens1->valueint);}} if (object2 != NULL && cJSON_IsObject(object2)) {cJSON *sens2 = cJSON_GetObjectItem(object2, "K4");  // 第二个对象中有名为 K4 的字段if (sens2 != NULL && cJSON_IsNumber(sens2)) {car.sens2 = sens2->valueint;printf("sens2: %d\n", sens2->valueint);}}}}cJSON_Delete(cjson);return 0;
}

3、解析(参考形式)

注释:借鉴参考文章

3.1、解析 {}

1

{/*************** 方式一 ***************/item = cJSON_GetObjectItem(root, "interest");		// 获取object对象名if (item != NULL) {cJSON *val = NULL;val = cJSON_GetObjectItem(item, "basketball");	// 根据object对象名获得里面的basketball数据if (val != NULL && val->type == cJSON_String) {v_str = val->valuestring;printf("basketball = %s\n", v_str);}val = cJSON_GetObjectItem(item, "badminton");	// 根据object对象名获得里面的badminton数据if (val != NULL && val->type == cJSON_String) {v_str = val->valuestring;printf("badminton = %s\n", v_str);}}/*************** 方式二 ***************/item = cJSON_GetObjectItem(root, "interest");if (item != NULL) {cJSON *obj = item->child;	// 获得 "basketball":	"篮球"while (obj) {if (obj->type == cJSON_String) {char *v_str = obj->valuestring;printf("%s = %s\n", obj->string, v_str);	// 可以通过string获得键}// 获取下一个元素obj = obj->next;}}
}

3.2、解析 [ ]

2

{/*************** 方式一 ***************/item = cJSON_GetObjectItem(root, "color");if (item != NULL) {int size = cJSON_GetArraySize(item);	// 获得数组个数for (int i = 0; i < size; i++) {cJSON *arr = cJSON_GetArrayItem(item, i);	// 根据索引获得数组中的值if (arr != NULL && arr->type == cJSON_String) {v_str = arr->valuestring;printf("color = %s\n", v_str);}}}/*************** 方式二 ***************/item = cJSON_GetObjectItem(root, "color");if (item != NULL) {cJSON *arr = item->child;	// 获得 "black"while (arr) {if (arr->type == cJSON_String) {char *v_str = arr->valuestring;printf("color = %s\n", v_str);}// 获取下一个元素arr = arr->next;}}
}

3.3、解析 [ {} {} ]

3

{/*************** 方式一 ***************/item = cJSON_GetObjectItem(root, "like");if (item != NULL) {int size = cJSON_GetArraySize(item);	// 获取的数组大小for (int i = 0; i < size; i++) {cJSON *obj = cJSON_GetArrayItem(item, i);		// 获取的数组里的objcJSON *val = NULL;if (obj != NULL && obj->type == cJSON_Object) {	// 判断数字内的元素是不是obj类型val = cJSON_GetObjectItem(obj, "game");		// 获得obj里的值if (val != NULL && val->type == cJSON_String) {v_str = val->valuestring;printf("game = %s\n", v_str);}val = cJSON_GetObjectItem(obj, "price");if (val != NULL && val->type == cJSON_Number) {v_double = val->valuedouble;printf("price = %.2f\n", v_double);}}}}/*************** 方式二 ***************/item = cJSON_GetObjectItem(root, "like");if (item != NULL) {cJSON *obj = item->child;	// 获得 { "game": "马里奥", "price": 66.6 }while (obj) {if (obj->type == cJSON_Object) {cJSON *objValue = obj->child;	// 获得 "game": "马里奥"while (objValue) {// 再通过类型去区分if (objValue->type == cJSON_String) {char *v_str = objValue->valuestring;printf("%s = %s\n", objValue->string, v_str);} else if (objValue->type == cJSON_Number) {double v_double = objValue->valuedouble;printf("%s = %.2f\n", objValue->string, v_double);}// 获取下一个元素objValue = objValue->next;}}// 获取下一组元素obj = obj->next;}}
}

3.4、解析[ [ ] [ ] ]

4

{/*************** 方式一 ***************/item = cJSON_GetObjectItem(root, "education");if (item != NULL) {int size = cJSON_GetArraySize(item);	// 获取的数组大小for (int i = 0; i < size; i++) {cJSON *arr = cJSON_GetArrayItem(item, i);		// 解析获得	[ "小学", "初中" ]if (arr != NULL && arr->type == cJSON_Array) {int arrSize = cJSON_GetArraySize(arr);for (int j = 0; j < arrSize; j++) {cJSON *arr2 = cJSON_GetArrayItem(arr, j);	// 再进一步解析就可以得到数组里面的元素了if (arr2 != NULL && arr2->type == cJSON_String) {v_str = arr2->valuestring;printf("education = %s\n", v_str);}}}}}/*************** 方式二 ***************/item = cJSON_GetObjectItem(root, "education");if (item != NULL) {cJSON *arr = item->child;	// 获得 [ "小学", "初中" ]while (arr) {if (arr->type == cJSON_Array) {cJSON *arrValue = arr->child;	// 获得 "小学"while (arrValue) {if (arrValue->type == cJSON_String) {char *v_str = arrValue->valuestring;printf("education = %s\n", v_str);}arrValue = arrValue->next;	// 获取下一个元素}}// 获取下一组arr = arr->next;}}
}

3.5、解析 { { } { } }

5

{/*************** 方式一 ***************/char *arrStr[] = { "serialOne", "serialTwo" };		// 可以提前定义需要解析的对象键,这样就可以使用for循环进行解析了item = cJSON_GetObjectItem(root, "languages");if (item != NULL) {cJSON *val = NULL;int size = sizeof(arrStr) / sizeof(char *);// 通过遍历指针数组,获得每个对象的键,在进行解析操作(如果不使用for循环解析,那就老老实实的写代码将全部个数解析完毕)for (int i = 0; i < size; i++) {cJSON *obj1 = cJSON_GetObjectItem(item, arrStr[i]);if (obj1 != NULL && obj1->type == cJSON_Object) {val = cJSON_GetObjectItem(obj1, "language");if (val != NULL && val->type == cJSON_String) {v_str = val->valuestring;printf("education = %s\n", v_str);}val = cJSON_GetObjectItem(obj1, "grade");if (val != NULL && val->type == cJSON_Number) {v_int = val->valueint;printf("grade = %d\n", v_int);}}}}/*************** 方式二 ***************/// 在不知道键是什么的情况下 和 不知道有多少元素的情况下可用item = cJSON_GetObjectItem(root, "languages");if (item != NULL) {// 获取到languages里的第一个子元素cJSON *obj = item->child;	// 也就是:"serialOne": { "language": "汉语", "grade": 10 }while (obj) {if (obj->type == cJSON_Object) {// 获取到子元素的子元素cJSON *value = obj->child;	// 也就是:{ "language": "汉语", "grade": 10 }while (value) {if (value->type == cJSON_String) {printf("%s = %s\n", value->string, value->valuestring);} else if (value->type == cJSON_Number) {printf("%s = %d\n", value->string, value->valueint);}// 通过next可以自由获取里面的元素了value = value->next;}}// 获得下一组子元素obj = obj->next;}}
}

参考文章

cJSON库用法详解
Cjson入门快速使用
使用cjson库 操作Json格式文件(创建、插入、解析、修改、删除)

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

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

相关文章

看看《MATLAB科研绘图与学术图表绘制从入门到精通》示例:绘制山鸢尾萼片长度和萼片宽度的小提琴图

使用MATLAB绘制鸢尾花数据集&#xff08; fisheriris&#xff09;中山鸢尾&#xff08; Iris Setosa&#xff09;的萼片长度和 萼片宽度的小提琴图。这将帮助我们更好地了解山鸢尾的这两个特征的数据分布情况&#xff0c;包括它们的 中位数、四分位范围及密度估计。这种可视化工…

华为配置路由式Proxy ARP示例

配置路由式Proxy ARP示例 组网图形 图1 配置路由式Proxy ARP组网图 路由式Proxy ARP简介配置注意事项组网需求配置思路操作步骤配置文件 路由式Proxy ARP简介 企业内部进行子网划分时&#xff0c;可能会出现两个子网网络属于同一网段&#xff0c;但是却不属于同一物理网络的情…

C++ 类模板分文件编写

类模板分文件编写&#xff1a; 类模板成员函数 分文件编写 产生的问题以及解决方式是什么呢&#xff1f; 问题描述 类模板中**成员函数**创建时机是在**调用**阶段&#xff0c;导致分文件编写时**链接**不到 解决方案&#xff1a; 1、直接包含.cpp源文件&#xff1a; person…

【重磅更新】开源表单系统填鸭表单v5版发布!

亲爱的TDucker&#xff0c;你们好。 真诚感谢您对填鸭表单的关注与支持。今天我们将为您带来新版本的更新说明&#xff0c;以便您更好的使用我们的产品。 社区版版V5更新概览&#xff1a; ✅ 增加WebHook数据推送功能&#xff0c;集成TReport实现数据大屏展示。 ✅ 增加主题…

LeetCode-Java:303、304区域检索(前缀和)

文章目录 题目303、区域和检索&#xff08;数组不可变&#xff09;304、二维区域和检索&#xff08;矩阵不可变&#xff09; 解①303&#xff0c;一维前缀和②304&#xff0c;二维前缀和 算法前缀和一维前缀和二维前缀和 题目 303、区域和检索&#xff08;数组不可变&#xff…

DateTimeFormat 和 JsonFormat 应用场景详解

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

【javaWeb 第七篇】后端-Spring

Spring SpringspringBoot请求简单参数实体参数数组集合参数日期参数JSON参数路径参数 响应数据分层解耦三层架构解耦操作Bean的声明Bean组件扫描问题DI详解 Spring 详细介绍结合官网查看&#xff1a;https://spring.io/why-spring Spring发展到今天已经形成一种开发生态圈&…

覆盖最全面的学术论文写作的70类细节150+ChatGPT提示词

点击下方▼▼▼▼链接直达AIPaperPass &#xff01; AIPaperPass - AI论文写作指导平台 这篇文章小编介绍了专门为论文写作定制的ChatGPT提示词&#xff0c;旨在激发创造力并为你的论文提供独特的想法和见解。通过简单的短语或指令&#xff0c;你可以解锁ChatGPT AI模型的潜力…

激光车型识别仪:交通管理领域的技术革新与应用探索

激光车型识别仪&#xff1a;交通管理领域的技术革新与应用探索 在交通管理领域&#xff0c;随着技术的不断进步&#xff0c;各种智能化设备逐渐崭露头角。其中&#xff0c;激光车型识别仪作为一种基于激光技术的车辆识别设备&#xff0c;正以其高精度、强抗干扰能力等特点&…

JIT在汽车行业中的革命性应用:颠覆传统制造模式,引领智能制造新时代

随着科技的飞速发展和市场竞争的日益激烈&#xff0c;汽车行业正面临着前所未有的变革。其中&#xff0c;准时制生产&#xff08;Just-In-Time&#xff0c;简称JIT&#xff09;作为一种先进的生产管理方式&#xff0c;已经在汽车行业中得到了广泛应用&#xff0c;成为推动汽车产…

word文件的创建时间和修改时间可以更改吗?答案是肯定的 文件属性修改的方法

一&#xff0c;引言 在日常生活和工作中&#xff0c;我们经常需要处理各种Word文件。有时&#xff0c;由于某些原因&#xff0c;我们可能需要更改Word文件的创建时间和修改时间。虽然这听起来可能有些复杂&#xff0c;但实际上&#xff0c;通过一些简单的方法和工具&#xff0…

社区养老服务系统|基于springboot社区养老服务系统设计与实现(源码+数据库+文档)

社区养老服务系统目录 目录 基于springboot社区养老服务系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、管理员部分功能 &#xff08;1&#xff09; 用户管理 &#xff08;2&#xff09;服务种类管理 &#xff08;3&#xff09;社区服务管理 &#xff08…

【数据分析面试】21.Spotify 音乐数据库搭建(SQL主键和外键)

题目&#xff1a;音乐数据库设计 假设现在你在Spotify工作&#xff0c;你需要设计一个用于存储歌曲元数据的关系型数据库。 数据库要求包括歌曲标题、歌曲长度、歌曲添加到平台的日期、艺术家、专辑、曲目号&#xff08;在专辑中的顺序&#xff09;、歌曲的发行年份以及流派等…

FebHost:为什么注册.BE比利时域名?

.be 是比利时的国家代码顶级域名&#xff08;ccTLD&#xff09;&#xff0c;通常用于与该国有关的网网站。这个域名为那些希望在线上建立与比利时有关联系的个人、公司和组织提供了一个重要的网络标识。 .be 域名于1988年创建&#xff0c;由.BE域名注册机构管理&#xff0c;这…

【k8s】:深入理解 Kubernetes 中的污点(Taints)与容忍度(Tolerations)

【k8s】&#xff1a;深入理解 Kubernetes 中的污点&#xff08;Taints&#xff09;与容忍度&#xff08;Tolerations&#xff09; 1、污点&#xff08;Taints&#xff09;2、容忍度&#xff08;Tolerations&#xff09;3、示例演示-测试污点的具体应用场景3.1 给节点打污点&…

HarmonyOS开发案例:【智能煤气检测】

样例简介 智能煤气检测系统通过实时监测环境中烟雾浓度&#xff0c;当一氧化碳浓度超标时&#xff0c;及时向用户发出警报。在连接网络后&#xff0c;配合数字管家应用&#xff0c;用户可以远程配置智能煤气检测系统的报警阈值&#xff0c;远程接收智能煤气检测系统报警信息。…

多轴机械臂/正逆解/轨迹规划/机器人运动学/Matlab/DH法 学习记录02——机械臂几何法与DH表示法

系列文章目录 本科毕设正在做多轴机械臂相关的内容&#xff0c;这里是一个学习机械臂运动学课程的相关记录。 如有任何问题&#xff0c;可发邮件至layraliufoxmail.com问询。 1. 数学基础 2. 机械臂几何法与DH表示法 文章目录 系列文章目录一、手臂几何法1.机械手臂2.机械手臂…

4.配置USART串口实现printf打印

通过TTL转USB实现电脑和单片机连通,是我们调试必不可少的工具 查看原理图,使用USART1,它们的TX和RX分别在PA9和PA10 新建Usart.c存放串口模块的初始化 这段代码是复制了正点原子的工程,添加到前面 #if SYSTEM_SUPPORT_OS #include "includes.h" //ucos 使用 …

每日两题 / 15. 三数之和 73. 矩阵置零(LeetCode热题100)

15. 三数之和 - 力扣&#xff08;LeetCode&#xff09; 先确定一个数t&#xff0c;对于剩下的两个数&#xff0c;要求两数之和为t的负数 三数之和就退化成了两数之和&#xff0c;两数之和可以用双指针 先排序&#xff0c;左右两个指针&#xff0c;指向的数之和大于目标值&…

AI启示录:既是企业安全利器,也是内部隐藏炸弹

目录 发现潜在威胁->成为内部威胁 精准检测威胁->扰乱正常业务 深度学习->数据中毒 随着网络威胁的迅速发展&#xff0c;专家预计&#xff0c;到 2024 年网络犯罪将给美国公司带来高达 4520 亿美元的损失&#xff0c;且这一数字在未来几年还会迅速增长。除了网络安全措…