通讯录完善版本(详细讲解+源码)

目录

前言

一、使通讯可以动态更新内存

1、contact.h

2、contact.c

存信息:

删除联系人,并试一个不存在的人的信息,看看会不会把其他人删了

​编辑

修改:

​编辑

排序:

​编辑

销毁:

​编辑

​编辑

二、通讯录的信息保存,加载

通讯录的信息保存;

再增加一个保存信息的函数

Save_Contact:

再增加一个从文件中加载信息的函数

Load_Contact:

​编辑

​编辑

三、下面是完整的代码:

test.c

castact.c

contact.h

总结


前言

     经过长达六个月的时间,年迈的博主终于想起来,通讯录还需要完善,那么这篇文章就对我们的初代通讯录(初代通讯录(详细讲解+代码)_化学系通讯录最简单三个步骤-CSDN博客)进行完善,增加动态更新内存的内容,以及建立一个文件,将通讯录的信息保存下来;


一、使通讯可以动态更新内存

我们先看一下原通讯录

1、contact.h
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<math.h>
#pragma once#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 30
#define MAX 100//定义人的信息
typedef struct PeoInfo
{char name[NAME_MAX];char sex[SEX_MAX];int age;char tele[TELE_MAX];char addr[ADDR_MAX];
}PeoInfo;//定义通讯录的信息
typedef struct Contact
{PeoInfo data[MAX];//存放人的信息int sz;//记录目前通讯录中存放的人的信息个数
}Contact;//初始化通讯录
void Init_Contact(Contact* pc);
//增加联系人
void Add_Contact(Contact* pc);
//删除联系人
void Del_Contact(Contact* pc);
查找联系人
void Search_Contact(Contact* pc);
修改联系人信息
void Modify_Contact(Contact* pc);
通讯录信息查看
void Show_Contact(Contact* pc);
通讯录信息排列
void Sort_Contact(Contact* pc);
2、contact.c
#include"contact.h"//初始化通讯录
void Init_Contact(Contact* pc)
{assert(pc);pc->sz = 0;memset(pc->data, 0, sizeof(pc->data));}
//增加联系人
void Add_Contact(Contact* pc)
{assert(pc);if (pc->sz == MAX){printf("通讯录满了,无法添加");return;}//添加一个联系人的信息//printf("请输入你要添加的联系人的信息:");//scanf("%-20s\t%-5s\t%-4d\t%-12s\t%-20s\n", pc->data[pc->sz].name, pc->data[pc->sz].sex, &(pc->data[pc->sz].age), pc->data[pc->sz].tele, pc->data[pc->sz].addr);printf("请输入姓名:");scanf("%s", pc->data[pc->sz].name);printf("请输入性别:");scanf("%s", pc->data[pc->sz].sex);printf("请输入年龄:");scanf("%d", &(pc->data[pc->sz].age)); printf("请输入电话:");scanf("%s", pc->data[pc->sz].tele);printf("请输入地址:");scanf("%s", pc->data[pc->sz].addr);pc->sz++;}
//删除联系人
void Del_Contact(Contact* pc)
{char name[NAME_MAX] = { 0 };if (pc->sz == 0){printf("通讯录为空,无法删除");return;}//不为空,删除printf("请输入要删除人的名字:");scanf("%s", name);int i = 0;int del = 0;for (i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0){del = i;break;}}for (i = del; i < pc->sz-1; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("已成功删除该联系人");}
//查找联系人
void Search_Contact(Contact* pc)
{char name[NAME_MAX] = { 0 };if (pc->sz == 0){printf("通讯录为空");return;}printf("请输入要查找的人的名字:");scanf("%s", name);int i = 0;int pos = 0;for (i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0){pos = i;			}}printf("%-20s\t%-5s\t%-4s\t%-12s\t%-20s\n", "名字", "性别", "年龄", "电话", "地址");printf("%-20s\t%-5s\t%-4d\t%-12s\t%-20s\n",pc->data[pos].name,pc->data[pos].sex,pc->data[pos].age,pc->data[pos].tele,pc->data[pos].addr);}
//修改联系人信息
void Modify_Contact(Contact* pc) 
{char name[NAME_MAX] = { 0 };if (pc->sz == 0){printf("通讯录为空,无法修改");return;}printf("请输入要修改的人的名字:");scanf("%s", name);int i = 0;int pos = 0;for (i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0){pos = i;}}printf("请输入姓名:");scanf("%s", pc->data[pos].name);printf("请输入性别:");scanf("%s", pc->data[pos].sex);printf("请输入年龄:");scanf("%d", &(pc->data[pos].age));printf("请输入电话:");scanf("%s", pc->data[pos].tele);printf("请输入地址:");scanf("%s", pc->data[pos].addr);}
//通讯录信息查看/打印通讯录
void Show_Contact(Contact* pc)
{assert(pc);printf("%-20s\t%-5s\t%-4s\t%-12s\t%-20s\n", "名字", "性别", "年龄", "电话", "地址");int i = 0;for (i = 0; i < pc->sz; i++){printf("%-20s\t%-5s\t%-4d\t%-12s\t%-20s\n",pc->data[i].name,pc->data[i].sex,pc->data[i].age,pc->data[i].tele,pc->data[i].addr);}}
int cmp_by_name(const void* e1, const void* e2)
{return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}//通讯录信息排列
void Sort_Contact(Contact* pc)
{assert(pc);if (pc->sz == 0){printf("通讯录为空,无法排序\n");return;}qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_by_name);printf("排序完成\n");}

可以看到原通讯录是用100大小的静态数组存储信息的,现在我们将其改为动态的数组;

主要是初始化,增加联系人,信息排列,销毁通讯录需要用到动态内存管理;

动态内存函数可以在这里看:动态内存函数_内存创建用什么函数-CSDN博客

我们先将定义进行更改,增加容量capacity,以及将存放信息的data数组不加限制;

然后在初始化Init_Contact这里进行修改,先设置初始容量capacity的值,然后再通过malloc设置初始内存,再用assert断言确保内存设置好了,不为空;

然后就是增加联系人这块,当通讯录满了即pc->sz == pc->capacity的时候,将pc->capacity乘2,增加容量,当然了,想扩大多少倍看你自己喜欢,然后再对存放数据的data数组经行扩容,扩成修改后的capacity大小;最后加个assert断言

然后是信息排列

最后是对动态数组的销毁,先将内存释放掉,然后置为空,再将capacitysz置为0;

将各个功能都试一下;

存信息:

删除联系人,并试一个不存在的人的信息,看看会不会把其他人删了

修改:

排序:

销毁:

ok,这边的通讯录动态数组已经没问题,我们接着来看

二、通讯录的信息保存,加载

通讯录的信息保存,加载涉及文件的读写操作:c语言文件操作-CSDN博客

通讯录的信息保存;

首先创建一个记事本文档,再在代码中定义上

然后完善增加两个函数的目录

#include"contact.h"
void menu()
{printf("**************************************\n");printf("****** 1.add     2.del     ***********\n");printf("****** 3.search  4.modify  ***********\n");printf("****** 5.show    6.sort    ***********\n");printf("****** 7.save    8.load    ***********\n");printf("****** 0.exit   9.destory  ***********\n");printf("**************************************\n");}
enum
{Exit,Add,Del,Search,Modify,Show,Sort,Save,Load,Destory
};//directory
int main()
{//创建通讯录Contact con;Init_Contact(&con);int input = 0;do{menu();printf("请输入:");scanf("%d", &input);switch (input){case Exit:printf("已退出通讯录\n");break; case Add:Add_Contact(&con);break;case Del:Del_Contact(&con);break;case Search:Search_Contact(&con);break;case Modify:Modify_Contact(&con);break;case Show:Show_Contact(&con);break;case Sort:Sort_Contact(&con);break;case Save:Save_Contact(&con);break; case Load:Load_Contact(&con);break;case Destory:Destory_Contact(&con); break;default:printf("选择错误,请重新选择\n");break;}	} while (input);//Destory_Contact(&con);return 0;
}

再增加一个保存信息的函数

Save_Contact:

void Save_Contact(Contact* pc) {assert(pc);FILE* file = fopen(FILENAME, "w");if (!file) {printf("无法打开文件进行保存\n");return;}for (int i = 0; i < pc->sz; i++) {fprintf(file, "%s %s %d %s %s\n",pc->data[i].name,pc->data[i].sex,pc->data[i].age,pc->data[i].tele,pc->data[i].addr);}fclose(file);printf("联系人信息已经保存到文件\n");
}

再增加一个从文件中加载信息的函数

1. **打开文件**:
   - 使用 `fopen` 函数以只读模式打开指定的文件。如果文件打开失败,程序会输出错误信息并返回。

2. **动态扩展内存**:
   - 在读取每个联系人之前,检查当前的联系人数量 `sz` 是否达到了当前容量 `capacity`。如果达到了,就使用 `realloc` 扩展内存,以便可以存储更多的联系人信息。

3. **读取数据**:
   - 使用 `fscanf` 从文件中读取每个联系人的信息。格式字符串 `"%s %s %d %s %s\n"` 指定了要读取的数据类型:
     - `%s` 用于读取字符串(姓名、性别、电话、地址)。
     - `%d` 用于读取整数(年龄)。

4. **存储数据**:
   - 将读取到的数据存储到 `PeoInfo` 结构体的相应字段中。

为什么 `age` 需要加引用

在 C 语言中,`fscanf` 函数的工作原理是通过指针来修改变量的值。具体来说:

引用的概念:
 在 C 语言中,变量的值是存储在内存中的某个地址。当你想要修改一个变量的值时,你需要提供这个变量的地址。
  使用 `&` 符号可以获取变量的地址。例如,`&pc->data[pc->sz].age` 获取 `age` 字段的地址。

fscanf 的参数:
  fscanf的参数需要是指向变量的指针,以便它可以直接在内存中修改该变量的值。
  对于 age字段,fscanf需要知道它的地址,以便将读取到的整数值存储到这个地址中。因此,必须使用 `&` 符号。

 示例:

假设我们有以下代码:

int age;
fscanf(file, "%d", &age);

`&age` 将 `age` 变量的地址传递给 `fscanf`,这样 `fscanf` 就可以在该地址上写入读取到的整数值。
- 如果不使用 `&`,例如 `fscanf(file, "%d", age);`,编译器会报错,因为 `age` 是一个整数,而 `fscanf` 需要的是一个指向整数的指针。

Load_Contact:

void Load_Contact(Contact* pc) {assert(pc);FILE* file = fopen(FILENAME, "r");if (!file) {printf("无法打开文件进行加载\n");return;}while (!feof(file)) {if (pc->sz == pc->capacity) {pc->capacity *= 2;pc->data = (PeoInfo*)realloc(pc->data, pc->capacity * sizeof(PeoInfo));//重新分配assert(pc->data);//确保内存分配成功}fscanf(file, "%s %s %d %s %s\n",pc->data[pc->sz].name,pc->data[pc->sz].sex,&pc->data[pc->sz].age,pc->data[pc->sz].tele,pc->data[pc->sz].addr);pc->sz++;}fclose(file);printf("联系人信息已经加载\n");
}

再来验一下货,看看我们的代码灵不灵

应该是没有问题

三、下面是完整的代码:
test.c
#include"contact.h"
void menu()
{printf("**************************************\n");printf("****** 1.add     2.del     ***********\n");printf("****** 3.search  4.modify  ***********\n");printf("****** 5.show    6.sort    ***********\n");printf("****** 7.save    8.load    ***********\n");printf("****** 0.exit   9.destory  ***********\n");printf("**************************************\n");}
enum
{Exit,Add,Del,Search,Modify,Show,Sort,Save,Load,Destory
};//directory
int main()
{//创建通讯录Contact con;Init_Contact(&con);int input = 0;do{menu();printf("请输入:");scanf("%d", &input);switch (input){case Exit:printf("已退出通讯录\n");break; case Add:Add_Contact(&con);break;case Del:Del_Contact(&con);break;case Search:Search_Contact(&con);break;case Modify:Modify_Contact(&con);break;case Show:Show_Contact(&con);break;case Sort:Sort_Contact(&con);break;case Save:Save_Contact(&con);break; case Load:Load_Contact(&con);break;case Destory:Destory_Contact(&con); break;default:printf("选择错误,请重新选择\n");break;}	} while (input);//Destory_Contact(&con);return 0;
}
castact.c
#include"contact.h"//初始化通讯录
void Init_Contact(Contact* pc)
{assert(pc);pc->sz = 0;pc->capacity = 2;//设置初始容量pc->data = (PeoInfo*)malloc(pc->capacity * sizeof(PeoInfo));//初始内存assert(pc->data);//确保内存不为空}
//增加联系人
void Add_Contact(Contact* pc)
{assert(pc);if (pc->sz == pc->capacity){//printf("通讯录满了,无法添加");//return;pc->capacity *= 2;pc->data = (PeoInfo*)realloc(pc->data,pc->capacity*sizeof(PeoInfo));assert(pc->data);//确保内存分配成功}//添加一个联系人的信息//printf("请输入你要添加的联系人的信息:");//scanf("%-20s\t%-5s\t%-4d\t%-12s\t%-20s\n", pc->data[pc->sz].name, pc->data[pc->sz].sex, &(pc->data[pc->sz].age), pc->data[pc->sz].tele, pc->data[pc->sz].addr);printf("请输入姓名:");scanf("%s", pc->data[pc->sz].name);printf("请输入性别:");scanf("%s", pc->data[pc->sz].sex);printf("请输入年龄:");scanf("%d", &(pc->data[pc->sz].age)); printf("请输入电话:");scanf("%s", pc->data[pc->sz].tele);printf("请输入地址:");scanf("%s", pc->data[pc->sz].addr);pc->sz++;}
//删除联系人
void Del_Contact(Contact* pc)
{char name[NAME_MAX] = { 0 };if (pc->sz == 0){printf("通讯录为空,无法删除");return;}//不为空,删除printf("请输入要删除人的名字:");scanf("%s", name);int i = 0;int del = -1;for (i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0){del = i;break;}}if (del == -1) {printf("未找到该联系人");return;}for (i = del; i < pc->sz-1; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("已成功删除该联系人");}
//查找联系人
void Search_Contact(Contact* pc)
{char name[NAME_MAX] = { 0 };if (pc->sz == 0){printf("通讯录为空");return;}printf("请输入要查找的人的名字:");scanf("%s", name);int i = 0;int pos = 0;for (i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0){pos = i;	printf("%-20s\t%-5s\t%-4s\t%-12s\t%-20s\n", "名字", "性别", "年龄", "电话", "地址");printf("%-20s\t%-5s\t%-4d\t%-12s\t%-20s\n",pc->data[pos].name,pc->data[pos].sex,pc->data[pos].age,pc->data[pos].tele,pc->data[pos].addr);return;}}printf("未找到该联系人");}
//修改联系人信息
void Modify_Contact(Contact* pc) 
{char name[NAME_MAX] = { 0 };if (pc->sz == 0){printf("通讯录为空,无法修改");return;}printf("请输入要修改的人的名字:");scanf("%s", name);int i = 0;int pos = 0;for (i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0){pos = i;printf("请输入姓名:");scanf("%s", pc->data[pos].name);printf("请输入性别:");scanf("%s", pc->data[pos].sex);printf("请输入年龄:");scanf("%d", &(pc->data[pos].age));printf("请输入电话:");scanf("%s", pc->data[pos].tele);printf("请输入地址:");scanf("%s", pc->data[pos].addr);return;}}printf("未找到该联系人");}
//通讯录信息查看/打印通讯录
void Show_Contact(Contact* pc)
{assert(pc);printf("%-20s\t%-5s\t%-4s\t%-12s\t%-20s\n", "名字", "性别", "年龄", "电话", "地址");int i = 0;for (i = 0; i < pc->sz; i++){printf("%-20s\t%-5s\t%-4d\t%-12s\t%-20s\n",pc->data[i].name,pc->data[i].sex,pc->data[i].age,pc->data[i].tele,pc->data[i].addr);}}
int cmp_by_name(const void* e1, const void* e2)
{return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}//通讯录信息排列
void Sort_Contact(Contact* pc)
{assert(pc);if (pc->sz == 0){printf("通讯录为空,无法排序\n");return;}//qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_by_name);qsort(pc->data, pc->sz, sizeof(PeoInfo), cmp_by_name);printf("排序完成\n");}
void Destory_Contact(Contact* pc)
{assert(pc);free(pc->data);//释放内存/*if (pc->sz == 0){printf("通讯录为空\n");return;}for (int i =pc->sz; i >=0; i--){pc->sz--;pc->data[i] = pc->data[i + 1];}*/pc->data = NULL;//置空pc->sz = 0;pc->capacity = 0;printf("已全部删除,通讯录销毁\n");}void Save_Contact(Contact* pc) {assert(pc);FILE* file = fopen(FILENAME, "w");if (!file) {printf("无法打开文件进行保存\n");return;}for (int i = 0; i < pc->sz; i++) {fprintf(file, "%s %s %d %s %s\n",pc->data[i].name,pc->data[i].sex,pc->data[i].age,pc->data[i].tele,pc->data[i].addr);}fclose(file);printf("联系人信息已经保存到文件\n");
}void Load_Contact(Contact* pc) {assert(pc);FILE* file = fopen(FILENAME, "r");if (!file) {printf("无法打开文件进行加载\n");return;}while (!feof(file)) {if (pc->sz == pc->capacity) {pc->capacity *= 2;pc->data = (PeoInfo*)realloc(pc->data, pc->capacity * sizeof(PeoInfo));//重新分配assert(pc->data);//确保内存分配成功}fscanf(file, "%s %s %d %s %s\n",pc->data[pc->sz].name,pc->data[pc->sz].sex,&pc->data[pc->sz].age,pc->data[pc->sz].tele,pc->data[pc->sz].addr);pc->sz++;}fclose(file);printf("联系人信息已经加载\n");
}
contact.h
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>
#include<math.h>
#pragma once
#define FILENAME "contacts.txt"//文件名#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 30
//#define MAX 1000//定义人的信息
typedef struct PeoInfo
{char name[NAME_MAX];char sex[SEX_MAX];int age;char tele[TELE_MAX];char addr[ADDR_MAX];
}PeoInfo;//定义通讯录的信息
typedef struct Contact
{//PeoInfo data[MAX];//存放人的信息PeoInfo* data;//存放人的信息int sz;//记录目前通讯录中存放的人的信息个数int capacity;//记录目前容量
}Contact;//初始化通讯录
void Init_Contact(Contact* pc);
//增加联系人
void Add_Contact(Contact* pc);
//删除联系人
void Del_Contact(Contact* pc);
查找联系人
void Search_Contact(Contact* pc);
修改联系人信息
void Modify_Contact(Contact* pc);
通讯录信息查看
void Show_Contact(Contact* pc);
通讯录信息排列
void Sort_Contact(Contact* pc);
//通讯录删除全部联系人
void Destory_Contact(Contact* pc);void Save_Contact(Contact* pc); //保存void Load_Contact(Contact* pc);//加载


总结

首先非常感谢大家的观看,这期对通讯录进行了完善,增加了动态变化数组已经信息的保存与加载

修改了很多缺陷:

1.这个通讯录能保存了,不会出现一旦退出就消失了

2.这个通讯录没有固定大小,减少了空间的浪费

本期内容到这里就结束了,有什么不足的地方可以提出来,我会虚心接受改进的,大家一起加油吧

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

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

相关文章

Linux操作系统复习

Linux操作系统复习 一. Linux的权限和shell原理1. Linux从广义上讲是什么 从狭义上讲是什么&#xff1f;2. shell是什么&#xff1f;3. 为什么要设置一个shell外壳而不是直接和linux 内核沟通4. shell的原理是什么5. Linux中权限的概念6. 如何提升当前操作的权限7. 文件访问者的…

Spring AI 快速入门:从环境搭建到核心组件集成

Spring AI 快速入门&#xff1a;从环境搭建到核心组件集成 一、前言&#xff1a;Java开发者的AI开发捷径 对于Java生态的开发者来说&#xff0c;将人工智能技术融入企业级应用往往面临技术栈割裂、依赖管理复杂、多模型适配困难等挑战。Spring AI的出现彻底改变了这一局面——…

C++11介绍

目录 一、C11的两个小点 1.1、decltype 1.2、nullptr 二、列表初始化 2.1、C98传统的{} 2.2、C11中的{} 2.3、C11中的std::initializer_list 三、右值引用和移动语义 3.1、左值和右值 3.2、左值引用和右值引用 3.3、引用延长生命周期 3.4、左值和右值的参数匹配 3…

基于机器学习的网络钓鱼邮件智能检测与防护系统

phishingDP 介绍 phishingDP 是一个基于机器学习的网络钓鱼邮件智能检测与防护系统&#xff0c;旨在通过深度学习技术识别潜在的钓鱼邮件&#xff0c;保护用户免受网络诈骗威胁。该系统集成了数据预处理、模型训练、实时预测和结果可视化功能&#xff0c;提供用户友好的Web界…

OpenAI 推出「轻量级」Deep Research,免费用户同享

刚刚&#xff0c;OpenAI 正式上线了面向所有用户的「轻量级」Deep Research 版本&#xff0c;意味着即便没有付费订阅&#xff0c;也能体验这一强大工具的核心功能。 核心差异&#xff1a;o4-mini vs. o3 模型迭代 传统的深度研究功能基于更大规模的 o3 模型。轻量级版本则改以…

什么是优质的静态IP?以及如何选择优质的静态IP?

在如今的大数据生态中&#xff0c;静态IP的使用频率和重要性不断提升。但是&#xff0c;我们常听到业界提到“优质的静态IP”&#xff0c;那么什么样的静态IP能够称之为优质&#xff1f;如何判断这些IP能否满足我们的需求&#xff1f;今天这篇文章&#xff0c;将为您揭开优质静…

Hadoop生态圈框架部署 - Windows上部署Hadoop

文章目录 前言一、下载Hadoop安装包及bin目录1. 下载Hadoop安装包2. 下载Hadoop的bin目录 二、安装Hadoop1. 解压Hadoop安装包2. 解压Hadoop的Windows工具包 三、配置Hadoop1. 配置Hadoop环境变量1.1 打开系统属性设置1.2 配置环境变量1.3 验证环境变量是否配置成功 2. 修改Had…

搜广推校招面经八十一

OPPO搜广推一面面经 一、介绍一下PLE模型 在多任务学习&#xff08;Multi-Task Learning, MTL&#xff09;中&#xff0c;多个任务共享部分模型结构&#xff0c;以提升整体效果。然而&#xff0c;不同任务间存在 任务冲突&#xff08;Task Conflict&#xff09; 问题&#xf…

LangChain 中主流的 RAG 实现方式

文章目录 **一、基础流程实现**1. **全自动索引构建&#xff08;VectorstoreIndexCreator&#xff09;**2. **标准问答链&#xff08;RetrievalQA&#xff09;**3. **Document Chain 手动检索**4. **load_qa_chain&#xff08;传统方式&#xff09;** **二、高级定制化实现**1…

解决:springmvc工程 响应时,将实体类对象 转换成json格式数据

问题&#xff1a;一直无法将user对象转成json格式 按理来说&#xff0c;我在类上使用RestController注解&#xff0c;就可以实现将实体类对象写入响应体中&#xff0c;并作为json格式传递到客户端&#xff0c;但现实是没有生效&#xff0c;并且出现404&#xff0c;406&#xf…

【踩坑记录】stm32 jlink程序烧录不进去

最近通过Jlink给STM32烧写程序时一直报错&#xff0c;但是换一个其他工程就可以烧录&#xff0c;对比了一下jink配置&#xff0c;发现是速率选太高了“SW Device”&#xff0c;将烧录速率调整到10MHz以下就可以了

运维打铁:Mysql 分区监控以及管理

文章目录 一、简介二、设计逻辑1、配置文件检查2、创建逻辑3、 删除逻辑4、重建表分区逻辑5、recognize maxvalue分区表逻辑6、创建多个未来分区逻辑7、定时检测分区是否创建成功&#xff0c;否则发送告警邮件。 三、解决的问题四、配置例子与介绍 一、简介 操作数据库&#xf…

Appium自动化开发环境搭建

自动化 文章目录 自动化前言 前言 Appium是一款开源工具&#xff0c;用于自动化iOS、Android和Windows桌面平台上的本地、移动web和混合应用程序。原生应用是指那些使用iOS、Android或Windows sdk编写的应用。移动网页应用是通过移动浏览器访问的网页应用(appum支持iOS和Chrom…

《R语言SCI期刊论文绘图专题计划》大纲

今天开始&#xff0c;我将和大家分享系统且详细的《R语言SCI期刊绘图专题教程》&#xff0c;内容会从基础到高阶应用&#xff0c;从配色美学到顶刊风格复现&#xff0c;确保大家可以学到高质量内容&#xff01;下面是大纲。 &#x1f4da;《R语言SCI期刊论文绘图专题计划》 第…

STUN协议 与 TURN协议

STUN&#xff08;Session Traversal Utilities for NAT&#xff0c;NAT会话穿越应用程序&#xff09;是一种网络协议&#xff0c; STUN&#xff08;Simple Traversal of User Datagram Protocol through Network Address Translators (NATs)&#xff0c;NAT的UDP简单穿越&#…

在vscode终端中运行npm命令报错

解决方案 这个错误信息表明&#xff0c;你的系统&#xff08;可能是 Windows&#xff09;阻止了 PowerShell 执行脚本&#xff0c;这是由于 PowerShell 的执行策略导致的。PowerShell 的执行策略控制着在系统上运行哪些 PowerShell 脚本。默认情况下&#xff0c;Windows 可能…

手搓雷达图(MATLAB)

看下别人做出来什么效果 话不多说&#xff0c;咱们直接开始 %% 可修改 labels {用户等级, 发帖数, 发帖频率, 点度中心度, 中介中心度, 帖子类型计分, 被列为提案数}; cluster_centers [0.8, 4.5, 3.2, 4.0, 3.8, 4.5, 4.2; % 核心用户0.2, 0.5, 0.3, 0.2, 0.1, 0.0, 0.0;…

ViViT: 一种视频视觉Transformer

摘要 我们提出了基于纯transformer的视频分类模型,借鉴了这种模型在图像分类中的成功经验。我们的模型从输入视频中提取时空token,然后通过一系列transformer层进行编码。为了处理视频中遇到的长序列token,我们提出了几种高效的模型变种,这些变种将输入的空间和时间维度进…

嵌入式鸿蒙系统环境搭建与配置要求实现01

各位开发者大家好,今天主要给大家分享一下,鸿蒙系统的环境配置实现。 第一:鸿蒙配置基本要求 对电脑的要求,虚拟机配置建议 200GB 硬盘大小,10GB 内存,4*2CPU。 安装必要的依赖文件方法: sudo apt-get update && sudo apt-get install binutils git git-lfs g…

【多目标进化算法】常见多目标进化算法一览

算法全称核心特点备注NSGA-IINon-dominated Sorting Genetic Algorithm II非支配排序 拥挤度最经典&#xff0c;应用最广NSGA-IIINon-dominated Sorting Genetic Algorithm III支撑向量引导&#xff0c;适合高维&#xff08;3目标以上&#xff09;NSGA-II 的高维扩展版MOEA/DM…