C语言实现八种功能的通讯录(添加、删除、查找、修改、显示、排序、退出、清空)

通讯录功能概要及前提说明

此通讯录利用C语言完成,可以实现八种功能的通讯录(添加、删除、查找、修改、显示、排序、退出、清空)
在这里插入图片描述
代码由三部分组成,为什么要写成三部分而不写成一部分可以参考我以前的博客,如下:
链接: link

文章目录

  • 通讯录功能概要及前提说明
  • 1.通信录具体功能
  • 2.初始化菜单
  • 3.通讯录存储的信息
  • 4.通讯录基本框架
  • 6.各个部分功能模块声明
  • 7.初始化模块
  • 8.增加联系人模块
  • 9.显示通讯录模块
  • 10.删除用户模块
  • 11.查找用户模块
  • 12.修改用户信息模块
  • 13.排序用户信息模块
  • 14.清除模块
  • 15.完整源代码


1.通信录具体功能

通讯录可以用来存储100个人的信息,每个人的信息包括:姓名、性别、年龄、电话、住址

提供方法:
1.添加联系人信息
2.删除指定联系人信息
3.查找指定联系人信息
4.修改指定联系人信息
5.显示所有联系人信息
6.清空所有联系人
7.以名字/年龄/地址排序所有联系人

2.初始化菜单

void  menu()
{printf("*********************************************\n");printf("*********************************************\n");printf("*********************************************\n");printf("*********1.添加           2.删除*************\n");printf("*********3.查找           4.修改*************\n");printf("*********5.显示           6.排序*************\n");printf("*********7.退出           8.清空*************\n");printf("*********************************************\n");printf("*********************************************\n");printf("*********************************************\n");
}

3.通讯录存储的信息

使用 typedef 将 struct peoinfo 类型自定义成 peoinfo 更加方边后续使用。
利用宏定义设定各个参数的值,后续不需要再重新定义。

#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];int age;char sex[SEX_MAX];char tele[TELE_MAX];char addr[ADDR_MAX];}peoinfo;typedef struct contact
{peoinfo data[MAX];int sz;//记录当前人的信息个数
}contact;

其中,创建存放联系人的通讯录Contact,存放MAX个联系人对应的信息。sz用于记录当前储存联系人的数量。

4.通讯录基本框架

enum option
{add=1, del=2,search=3,modify,show,sort,run,clc	
};int main()
{int input = 0;contact con;//通讯录//初始化initcontact(&con);do{menu();printf("请输入功能:");scanf("%d", &input);switch (input){case add:addcontact(&con);break;case del:delcontact(&con);break;case search:searchcontact(&con);break;case modify:modifycontact(&con);break;case show:showcontact(&con);break;case sort:sortcontact(&con);break;case run:printf("退出通讯录\n");break;case clc:clccontact(&con);break;default:printf("输入非法,请重新输入!\n");break;}} while (input != 7);return 0;
}

我们知道case后只能加整数,为了更加直观的看到每一种功能,我们可以创建枚举类型替换这些整数,枚举类型成员的值从0开始递增1,适用于代替case后的整数,因为我么的菜单选项是从1到8,所以这里我们定义枚举的第一个值为1,这样后面就会默认排序到8。

通讯录运行通过do-while实现,内部调用menu函数打印开始菜单,然后提示用户选择功能。

6.各个部分功能模块声明

void initcontact(contact* pc);void addcontact(contact* pc);void showcontact(contact* pc);void delcontact(contact* pc);void searchcontact(contact* pc);void modifycontact(contact* pc);void sortcontact(contact* pc);void clccontact(contact* pc);

代码的基本框架搭建完毕,我们就要实现每一个选项的功能。这里是定义每一个功能的头文件,声明后才能在别的原文件中使用。

7.初始化模块

void initcontact(contact* pc)
{assert(pc);pc->sz = 0;memset(pc->data, 0, sizeof(pc->data));}

给定的代码是一个函数initcontact,它用于初始化一个名为contact的结构体指针pc。以下是对代码的分析:

①函数声明:void initcontact(contact* pc)

声明了一个名为initcontact的函数,它接受一个结构体指针pc作为参数,并且没有返回值(即返回类型为void)。

②断言:assert(pc) 断言确保pc指针不为空。如果pc为空,断言将失败,并导致程序终止。

③初始化:pc->sz = 0 将结构体指针pc的成员变量sz的值设置为0。这意味着将sz用作计数器或存储元素数量的变量。

④内存清零:memset(pc->data, 0, sizeof(pc->data))

使用memset函数将结构体指针pc的成员变量data的内存块清零。sizeof(pc->data)用于确定pc->data成员的大小,以确保清零操作覆盖整个内存块。

⑤通过这些操作,函数initcontact将结构体指针pc所指向的contact结构体进行初始化。初始化的结果是将sz设置为0,并将data的内存块清零。

8.增加联系人模块

void addcontact(contact* pc)
{assert(pc);if (pc->sz == MAX){printf("通讯录已满\n");return;}//增加信息printf("请输入名字:");scanf("%s", pc->data[pc->sz].name);printf("请输入年龄:");scanf("%d", &(pc->data[pc->sz].age));printf("请输入性别:");scanf("%s", pc->data[pc->sz].sex);printf("请输入电话:");scanf("%s", pc->data[pc->sz].tele);printf("请输入地址:");scanf("%s", pc->data[pc->sz].addr);pc->sz++;printf("通讯录已添加\n");Sleep(2000);
}

该代码定义了一个名为addcontact的函数,函数参数为一个指向contact结构体的指针pc。

①函数首先使用assert函数进行断言,确保指针pc不为空。

②然后判断通讯录的当前大小是否达到了最大值(MAX),如果达到了最大值则打印提示信息并返回。

③如果通讯录未满,则依次输入联系人的姓名、年龄、性别、电话和地址,并将这些信息保存到通讯录中。

④ 最后,将通讯录的大小加1,并打印添加成功的提示信息。使用Sleep函数暂停程序执行2秒后再弹出菜单继续选择。使使用者方便观察。

9.显示通讯录模块

void showcontact(contact* pc)
{assert(pc);if (pc->sz == 0){printf("通讯录为空\n");return;}int i = 0;printf("%-10s%-5s%-5s%-12s%-30s\n", "名字", "年龄", "性别", "电话", "地址");for (i = 0; i < pc->sz; i++){printf("%-10s%-5d%-5s%-12s%-30s\n", pc->data[i].name,pc->data[i].age,pc->data[i].sex,pc->data[i].tele,pc->data[i].addr);}Sleep(2000);
}

该代码定义了一个名为showcontact的函数,函数参数为一个指向contact结构体的指针pc。

①函数首先使用assert函数进行断言,确保指针pc不为空。

②然后判断通讯录的大小是否为0,如果为0则打印提示信息并返回。

③接下来,使用一个循环遍历通讯录中的每个联系人,并依次打印其姓名、年龄、性别、电话和地址。

④ 最后,使用Sleep函数暂停程序执行2秒。

需要注意的是,该代码依赖于一些未给出的头文件和结构体定义,例如contact结构体的定义。另外,该代码使用了格式化输出函数printf,其中使用了%-10s、%-5d等格式控制符,用于设置输出字段的宽度和对齐方式。

10.删除用户模块

int findname(contact* pc, char name[])
{assert(pc);int i = 0;for (i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0){return 1;}}return -1;
}void delcontact(contact* pc)
{char name[NAME_MAX];assert(pc);if (pc->sz == 0){printf("通讯录为空,无法删除\n");return;}printf("输入要删除人的名字:");scanf("%s", name);int ret = findname(pc,name);if (ret == -1){printf("要删除的人不存在\n");return;}int i = 0;for (i = ret; i <pc->sz-1 ; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功\n");Sleep(2000);
}

该代码定义了两个函数:findname和delcontact。

findname函数用于在通讯录中查找指定姓名的联系人,函数参数为一个指向contact结构体的指针pc和一个字符数组name。

①函数首先使用assert函数进行断言,确保指针pc不为空。

②然后使用一个循环遍历通讯录中的每个联系人,通过strcmp函数比较联系人的姓名是否与指定的name相等。如果相等,则返回1表示找到了该联系人。

③如果遍历完整个通讯录都没有找到匹配的姓名,则返回-1表示未找到。

④delcontact函数用于从通讯录中删除指定姓名的联系人,函数参数为一个指向contact结构体的指针pc。

⑤函数首先使用assert函数进行断言,确保指针pc不为空。

⑥然后判断通讯录的大小是否为0,如果为0则打印提示信息并返回。

⑦接下来,依次输入要删除的联系人的姓名,并调用findname函数查找该联系人是否存在。如果不存在,则打印提示信息并返回。

⑧如果存在,使用一个循环从找到的位置开始,将后面的联系人逐个往前移动一位,实现删除该联系人的功能。

⑨最后,将通讯录的大小减1,并打印删除成功的提示信息。使用Sleep函数暂停程序执行2秒。

11.查找用户模块

void searchcontact(contact* pc)
{char name[NAME_MAX];assert(pc);printf("请输入要查找人的姓名:");scanf("%s", name);int ret = findname(pc, name);if (ret == -1){printf("要查找的人不存在\n");return;}printf("查询成功!!\n");printf("%-10s%-5s%-5s%-12s%-30s\n", "名字", "年龄", "性别", "电话", "地址");printf("%-10s%-5d%-5s%-12s%-30s\n", pc->data[ret].name,pc->data[ret].age,pc->data[ret].sex,pc->data[ret].tele,pc->data[ret].addr);Sleep(2000);
}

该代码定义了一个名为searchcontact的函数,函数参数为一个指向contact结构体的指针pc。

①函数首先使用assert函数进行断言,确保指针pc不为空。

②然后输入要查找的联系人的姓名。

③接下来,调用findname函数查找该姓名的联系人在通讯录中的位置。如果返回值为-1,则打印提示信息并返回。

④如果返回值不为-1,表示找到了该联系人,打印查询成功的提示信息。

⑤然后,使用printf函数按照一定的格式打印该联系人的姓名、年龄、性别、电话和地址。

⑥最后,使用Sleep函数暂停程序执行2秒。

12.修改用户信息模块

void modifycontact(contact* pc)
{char name[NAME_MAX];assert(pc);printf("请输入要查找人的姓名:");scanf("%s", name);int ret = findname(pc, name);if (ret == -1){printf("要修改的人不存在\n");return;}printf("请输入名字:");scanf("%s", pc->data[ret].name);printf("请输入年龄:");scanf("%d", &(pc->data[ret].age));printf("请输入性别:");scanf("%s", pc->data[ret].sex);printf("请输入电话:");scanf("%s", pc->data[ret].tele);printf("请输入地址:");scanf("%s", pc->data[ret].addr);printf("修改成功!\n");}

该代码定义了一个名为modifycontact的函数,函数参数为一个指向contact结构体的指针pc。

①函数首先使用assert函数进行断言,确保指针pc不为空。

②然后输入要修改的联系人的姓名。

③接下来,调用findname函数查找该姓名的联系人在通讯录中的位置。如果返回值为-1,则打印提示信息并返回。

④如果返回值不为-1,表示找到了该联系人,依次输入要修改的联系人的姓名、年龄、性别、电话和地址,并将这些信息更新到通讯录中。

⑤最后,打印修改成功的提示信息。

13.排序用户信息模块

int cmp_name(const void* p1, const void* p2)
{return strcmp(((peoinfo*)p1)->name, ((peoinfo*)p2)->name);
}int cmp_age(const void* p1, const void* p2)
{return ((peoinfo*)p1)->age-((peoinfo*)p2)->age;
}int cmp_addr(const void* p1, const void* p2)
{return strcmp(((peoinfo*)p1)->addr, ((peoinfo*)p2)->addr);
}void sortcontact(contact* pc)
{int i = 0;char sort_choose[10];char sort_choose1[] = "name";char sort_choose2[] = "age";char sort_choose3[] = "addr";A:printf("请输入根据什么进行排序:");scanf("%s", sort_choose);if (strcmp(sort_choose,sort_choose1) == 0){//利用qsort 函数qsort(pc->data, pc->sz, sizeof((pc->data)[0]), cmp_name);}else if (strcmp(sort_choose,sort_choose2) == 0){qsort(pc->data, pc->sz, sizeof((pc->data)[1]), cmp_age);}else if (strcmp(sort_choose,sort_choose3) == 0){qsort(pc->data, pc->sz, sizeof((pc->data)[4]), cmp_addr);}else{printf("无此排序参数,请重新输入参数\n");goto A;}//打印列标题printf("%-10s%-5s%-5s%-12s%-30s\n", "名字", "年龄", "性别", "电话", "地址");//打印数据for (i = 0; i < pc->sz; i++){printf("%-10s%-5d%-5s%-12s%-30s\t\n",pc->data[i].name,pc->data[i].age,pc->data[i].sex,pc->data[i].tele,pc->data[i].addr);}Sleep(2000);
}

该代码定义了三个比较函数:cmp_name、cmp_age和cmp_addr。这些函数用于在排序通讯录时比较联系人信息的不同字段。

①cmp_name函数用于比较联系人姓名的大小,函数参数为指向两个联系人信息结构体的指针p1和p2。通过调用strcmp函数比较两个联系人的姓名,并返回比较结果。

② cmp_age函数用于比较联系人年龄的大小,函数参数为指向两个联系人信息结构体的指针p1和p2。通过将第一个联系人的年龄减去第二个联系人的年龄,并返回比较结果。

③cmp_addr函数用于比较联系人地址的大小,函数参数为指向两个联系人信息结构体的指针p1和p2。通过调用strcmp函数比较两个联系人的地址,并返回比较结果。

④sortcontact函数用于对通讯录中的联系人进行排序,函数参数为一个指向contact结构体的指针pc。

⑤函数首先定义一些变量和字符串数组用于接收用户输入的排序参数。

⑥然后,通过标签A实现一个循环,提示用户输入根据什么进行排序。根据用户的输入,分别调用qsort函数进行排序。排序时,根据用户的选择调用不同的比较函数。

⑦如果用户输入的排序参数无效,则打印提示信息并跳转回标签A,要求用户重新输入。

⑧排序完成后,先打印列标题,然后依次打印排序后的联系人信息。

⑨最后,使用Sleep函数暂停程序执行2秒。

14.清除模块

void clccontact(contact* pc)
{pc->sz = 0;memset(pc->data, 0, sizeof(pc->data));printf("通讯录已经清空!!!\n");Sleep(2000);
}

此代码实现了一个清空通讯录的函数。(即和初始化模块一样)函数接收一个指向联系人结构体的指针,将通讯录结构体中的数据清空,包括sz(通讯录中已有联系人数量)和data(存放联系人信息的数组)。最后输出提示信息“通讯录已经清空!!!”并延时2秒。

此代码的功能比较简单,只是清空通讯录。可以作为通讯录管理系统的一个基本操作函数之一。

15.完整源代码

test.c如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include "adressbook.h"void  menu()
{printf("*********************************************\n");printf("*********************************************\n");printf("*********************************************\n");printf("*********1.添加           2.删除*************\n");printf("*********3.查找           4.修改*************\n");printf("*********5.显示           6.排序*************\n");printf("*********7.退出           8.清空*************\n");printf("*********************************************\n");printf("*********************************************\n");printf("*********************************************\n");
}enum option
{add=1, del=2,search=3,modify,show,sort,run,clc	
};int main()
{int input = 0;contact con;//通讯录//初始化initcontact(&con);do{menu();printf("请输入功能:");scanf("%d", &input);switch (input){case add:addcontact(&con);break;case del:delcontact(&con);break;case search:searchcontact(&con);break;case modify:modifycontact(&con);break;case show:showcontact(&con);break;case sort:sortcontact(&con);break;case run:printf("退出通讯录\n");break;case clc:clccontact(&con);break;default:printf("输入非法,请重新输入!\n");break;}} while (input != 7);return 0;
}

addressbook.c如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include "adressbook.h"void initcontact(contact* pc)
{assert(pc);pc->sz = 0;memset(pc->data, 0, sizeof(pc->data));}void addcontact(contact* pc)
{assert(pc);if (pc->sz == MAX){printf("通讯录已满\n");return;}//增加信息printf("请输入名字:");scanf("%s", pc->data[pc->sz].name);printf("请输入年龄:");scanf("%d", &(pc->data[pc->sz].age));printf("请输入性别:");scanf("%s", pc->data[pc->sz].sex);printf("请输入电话:");scanf("%s", pc->data[pc->sz].tele);printf("请输入地址:");scanf("%s", pc->data[pc->sz].addr);pc->sz++;printf("通讯录已添加\n");Sleep(2000);
}void showcontact(contact* pc)
{assert(pc);if (pc->sz == 0){printf("通讯录为空\n");return;}int i = 0;printf("%-10s%-5s%-5s%-12s%-30s\n", "名字", "年龄", "性别", "电话", "地址");for (i = 0; i < pc->sz; i++){printf("%-10s%-5d%-5s%-12s%-30s\n", pc->data[i].name,pc->data[i].age,pc->data[i].sex,pc->data[i].tele,pc->data[i].addr);}Sleep(2000);
}int findname(contact* pc, char name[])
{assert(pc);int i = 0;for (i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0){return 1;}}return -1;
}void delcontact(contact* pc)
{char name[NAME_MAX];assert(pc);if (pc->sz == 0){printf("通讯录为空,无法删除\n");return;}printf("输入要删除人的名字:");scanf("%s", name);int ret = findname(pc,name);if (ret == -1){printf("要删除的人不存在\n");return;}int i = 0;for (i = ret; i <pc->sz-1 ; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功\n");Sleep(2000);
}void searchcontact(contact* pc)
{char name[NAME_MAX];assert(pc);printf("请输入要查找人的姓名:");scanf("%s", name);int ret = findname(pc, name);if (ret == -1){printf("要查找的人不存在\n");return;}printf("查询成功!!\n");printf("%-10s%-5s%-5s%-12s%-30s\n", "名字", "年龄", "性别", "电话", "地址");printf("%-10s%-5d%-5s%-12s%-30s\n", pc->data[ret].name,pc->data[ret].age,pc->data[ret].sex,pc->data[ret].tele,pc->data[ret].addr);Sleep(2000);
}void modifycontact(contact* pc)
{char name[NAME_MAX];assert(pc);printf("请输入要查找人的姓名:");scanf("%s", name);int ret = findname(pc, name);if (ret == -1){printf("要修改的人不存在\n");return;}printf("请输入名字:");scanf("%s", pc->data[ret].name);printf("请输入年龄:");scanf("%d", &(pc->data[ret].age));printf("请输入性别:");scanf("%s", pc->data[ret].sex);printf("请输入电话:");scanf("%s", pc->data[ret].tele);printf("请输入地址:");scanf("%s", pc->data[ret].addr);printf("修改成功!\n");}int cmp_name(const void* p1, const void* p2)
{return strcmp(((peoinfo*)p1)->name, ((peoinfo*)p2)->name);
}int cmp_age(const void* p1, const void* p2)
{return ((peoinfo*)p1)->age-((peoinfo*)p2)->age;
}int cmp_addr(const void* p1, const void* p2)
{return strcmp(((peoinfo*)p1)->addr, ((peoinfo*)p2)->addr);
}void sortcontact(contact* pc)
{int i = 0;char sort_choose[10];char sort_choose1[] = "name";char sort_choose2[] = "age";char sort_choose3[] = "addr";A:printf("请输入根据什么进行排序:");scanf("%s", sort_choose);if (strcmp(sort_choose,sort_choose1) == 0){//利用qsort 函数qsort(pc->data, pc->sz, sizeof((pc->data)[0]), cmp_name);}else if (strcmp(sort_choose,sort_choose2) == 0){qsort(pc->data, pc->sz, sizeof((pc->data)[1]), cmp_age);}else if (strcmp(sort_choose,sort_choose3) == 0){qsort(pc->data, pc->sz, sizeof((pc->data)[4]), cmp_addr);}else{printf("无此排序参数,请重新输入参数\n");goto A;}//打印列标题printf("%-10s%-5s%-5s%-12s%-30s\n", "名字", "年龄", "性别", "电话", "地址");//打印数据for (i = 0; i < pc->sz; i++){printf("%-10s%-5d%-5s%-12s%-30s\t\n",pc->data[i].name,pc->data[i].age,pc->data[i].sex,pc->data[i].tele,pc->data[i].addr);}Sleep(2000);
}void clccontact(contact* pc)
{pc->sz = 0;memset(pc->data, 0, sizeof(pc->data));printf("通讯录已经清空!!!\n");Sleep(2000);
}

addressbook.h如下:

#define _CRT_SECURE_NO_WARNINGS 1
#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 30
#define MAX 100#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <Windows.h>typedef struct peoinfo
{char name[NAME_MAX];int age;char sex[SEX_MAX];char tele[TELE_MAX];char addr[ADDR_MAX];}peoinfo;typedef struct contact
{peoinfo data[MAX];int sz;//记录当前人的信息个数
}contact;void initcontact(contact* pc);void addcontact(contact* pc);void showcontact(contact* pc);void delcontact(contact* pc);void searchcontact(contact* pc);void modifycontact(contact* pc);void sortcontact(contact* pc);void clccontact(contact* pc);

大家只需要将此代码,按照文章开头设置为三部分,点击运行即可。

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

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

相关文章

【PMP/软考】软件需求的三个主要层次:业务需求、用户需求和功能需求解释及实例解析

简述 当进行需求分析时&#xff0c;通常着重考虑三个主要层次&#xff1a;业务需求、用户需求和功能需求。业务需求关注项目与组织战略目标的一致性&#xff0c;用户需求明确最终用户的期望&#xff0c;而功能需求定义具体的系统功能和特性。这三个层次为项目管理和软件工程提…

基于改进莱维飞行和混沌映射的粒子群优化BP神经网络预测股票价格研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

[架构之路-223]:数据管理能力成熟度评估模型DCMM简介

目录 一、背景 二、评估依据 三、评估内容 四、主要适用对象 五、能力等级 六、不同层次的文件&#xff1a; 一、背景 信息技术与经济社会的交汇融合引发了数据爆发式增长。数据蕴含着重要的价值&#xff0c;已成为国家基础性战略资源&#xff0c;正日益对全球生产、流通…

更适合程序员体质的PPT制作工具——Slidev

Slidev简介 Slidev是什么 Slidev是一款基于Vue.js的现代化幻灯片制作工具&#xff0c;它可以帮助用户快速、高效地制作出美观、专业的幻灯片。 目前市面上有很多功能丰富的、通用的、所见即所得的幻灯片制作工具&#xff0c;例如 微软 PowerPoint 或 苹果 Keynote. 它们在制…

tp8 Editor.md

Editor.md - 开源在线 Markdown 编辑器 放于public文件夹下 html代码&#xff1a; <div class"layui-col-md12" id"content"><textarea name"content" placeholder"详情" class"layui-textarea">{notempty nam…

buuctf web [极客大挑战 2019]Upload

上传头像&#xff0c;上传一下&#xff0c;看看能不能成功 抓包&#xff0c;抓取上传时的数据,看看限制条件 改两个地方&#xff0c;符合上传图片的要求&#xff0c;上传试试 一句话木马的<?被扳了 改一下木马的格式 <script language"php">eval($_POST[cm…

Tomcat 开启远程调试

Tomcat 部署的 war包工程开启远程调试 Linux服务器下&#xff0c;编辑Tomcat bin 目录下的 startup.sh 文件 vim startup.sh在第一行加入&#xff1a;(不换行&#xff0c;在同一行) declare -x CATALINA_OPTS"-server -Xdebug -Xnoagent -Djava.compilerNONE -Xrunjdwp:…

Redis 集群搭建教程

一、介绍 Redis 集群有着高可用、易扩展、更好的性能等优势&#xff0c;本文主要是实战搭建一个三主三从的 Redis 集群。 正常来说&#xff0c;搭建 Redis 集群需要 6 台服务器。为了简单一点&#xff0c;本文通过一台服务器&#xff0c;6 个端口&#xff0c;搭建一个 Redis …

孜然单授权系统V1.0[免费使用]

您还在为授权系统用哪家而发愁&#xff1f;孜然单授权系统为您解决苦恼&#xff0c;本系统永久免费。 是的&#xff0c;还是那个孜然&#xff0c;消失了一年不是跑路了是没有空&#xff0c;但是这些都是无关紧要的&#xff0c;为大家带来的孜然单授权系统至上我最高的诚意&…

数据安全态势管理:什么是事实,什么是虚构?

考虑到组织存储大量数据的日益复杂的云环境&#xff0c;数据安全态势管理 ( DSPM )的兴起并不令人意外。使组织能够全面了解云数据资产和敏感数据的安全状况的流程对于当今的安全团队来说非常有价值。 尽管 DSPM 的重要性日益凸显&#xff0c;但人们对于它能为企业做什么和不能…

序列化对象(ObjectOutputStream,ObjectInputStream)

1、对象序列化 作用&#xff1a;以 内存 为基准&#xff0c;把内存中的对象存储到磁盘文件中去&#xff0c;称为对象序列化使用到的流是对象字节输出流&#xff1a;ObjectOutputStream package com.csdn.d7_serializable; import java.io.*; public class ObjectOutputStreamDe…

电脑开机慢问题的简单处理

电脑用久了&#xff0c;开机时间要10-20分钟特别慢&#xff0c;一下介绍两种简单有效处理方式&#xff0c;这两种方式经测试不会影响原系统软件的使用&#xff1a; 方式一&#xff1a;禁用非必要启动项【效果不是很明显】 利用360里面的优化加速禁用启动项【禁用启动项还有其…

大数据Flink(八十九):Temporal Join(快照 Join)

文章目录 Temporal Join(快照 Join) Temporal Join(快照 Join) Temporal Join 定义(支持 Batch\Streaming):Temporal Join 在离线的概念中其实是没有类似的 Join 概念的,但是离线中常常会维护一种表叫做 拉链快照表,使用一个明细表去 join 这个 拉链快照表 的 join …

【LeetCode-简单题】501. 二叉搜索树中的众数

文章目录 题目方法一&#xff1a;暴力哈希方法二&#xff1a;利用二叉搜索树的特性&#xff08;递归双指针&#xff09; 题目 方法一&#xff1a;暴力哈希 这是针对于普通二叉树的解法 统计number出现次数 然后将次数最大的众数集 取出来 Map<Integer , Integer > map …

Mysql备份恢复、与日志管理

Mysql日志管理、备份与恢复 一、Mysql日志管理1.1、日志分类1.1.1、错误日志1.1.2 、通用查询日志1.1.3、 二进制日志1.1.4 、慢查询日志1.1.5 、配置日志 1.2、日志的查询 二、备份与恢复2.1、 数据备份的必要性2.2 、造成数据丢失的原因2.3、 数据库备份的分类2.3.1、 物理备…

mysql-4:SQL的解析顺序

SQL语句的解析顺序 文章目录 SQL语句的解析顺序编写顺序与解析顺序解析顺序关键字FROMONOUTER JOINWHEREGROUP BYHAVINGSELECTDISTINCTORDER BYLIMIT 解析流程流程分析流程说明WHERE条件解析顺序 编写顺序与解析顺序 编写顺序 SELECT DISTINCT < select_list > FROM &l…

Linux C/C++下收集指定域名的子域名信息(类似dnsmap实现)

我们知道dnsmap是一个工具&#xff0c;主要用于收集指定域名的子域名信息。它对于渗透测试人员在基础结构安全评估的信息收集和枚举阶段非常有用&#xff0c;可以帮助他们发现目标公司的IP网络地址段、域名等信息。 dnsmap的操作原理 dnsmap&#xff08;DNS Mapping&#xff…

AMEYA360:瑞萨电子整合Reality AI工具与e² studio IDE,扩大其在AIoT领域的卓越地位

全球半导体解决方案供应商瑞萨电21日宣布已在其Reality AI Tools?和e2 studio集成开发环境间建立接口&#xff0c;使设计人员能够在两个程序间无缝共享数据、项目及AI代码模块。实时数据处理模块已集成至瑞萨MCU软件开发工具套件&#xff08;注&#xff09;&#xff0c;以方便…

Failed to load property source from location ‘classpath:/application.yml‘

前言 给同学部署项目的时候出现了这个错误&#xff0c;困扰我半天&#xff0c;搞了一下午&#xff0c;最后Google找到了答案。 在这里记录一下&#xff01; 解决方案 第一步&#xff1a;删除原有yml文件&#xff0c;把内容复制下来&#xff0c;重新写一个然后再粘贴进去 …

【yolov5】detect.py

执行方法: 代码 # YOLOv5 &#x1f680; by Ultralytics, AGPL-3.0 license """ Run YOLOv5 detection inference on images, videos, directories, globs, YouTube, webcam, streams, etc.Usage - sources:$ python detect.py --weights yolov5s.pt --source …