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

C语言/动态通讯录

本文使用了malloc、realloc、calloc等和内存开辟有关的函数。


文章目录

前言

二、头文件

三、主界面

四、通讯录功能函数

1.全代码

2.增加联系人

3.删除联系人

4.查找联系人

5.修改联系人

6.展示联系人

7.清空联系人

8.退出通讯录

总结


前言

为了使用通讯录时,可以随时调整大小,所以使用动态开辟内存函数写通讯录,可增加联系人容量。

动态开辟函数,即在内存的栈区开辟空间,所以使用完毕后,需要释放内存空间


一、通讯录运行图

二、头文件

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<assert.h>
#include<stdlib.h>#define Max 10enum function
{quit,increase,delete,find,revise,show,empty,sort
};typedef struct Person
{char name[20];size_t age;char sex[5];char address[30];char phone[12];
}person;//动态
typedef struct contact
{person *per;size_t sz;//通讯录已有人员个数size_t ContactMax;//通讯录当前最大容量
}contact;void init_contact(contact* con);void increase_contact(contact* con);void delete_contact(contact* con);//return -1(no) / address(yes)
int find1(const contact** con, size_t choice);
void find_contact(const contact* con);void revise_contact(contact* con);void show_contact(const contact* con);
//排序通讯录
void sort_contact(contact* con);
//销毁通讯录
void destroy_contact(contact* con);

三、主界面

#include "contact.h"void menu1()
{printf("**************************************\n");printf("******* Simplified address book ******\n");printf("*******   1> increase contact   ******\n");printf("*******   2> delete contact     ******\n");printf("*******   3> find contact       ******\n");printf("*******   4> revise contact     ******\n");printf("*******   5> Show all contacts  ******\n");printf("*******   6> Empty all contacts ******\n");printf("*******   7> Sort by name       ******\n");printf("*******   0> Quit Contacts      ******\n");printf("**************************************\n");
}void test()
{//create contactscontact con;//initialize contactsinit_contact(&con);size_t choice = 0;do{menu1();printf("Enter the feature options you need:");scanf("%u", &choice);switch (choice){case increase:increase_contact(&con);break;case delete:delete_contact( &con );break;case find:find_contact(&con);break;case revise:revise_contact(&con);break;case show:show_contact(&con);break;case empty:init_contact(&con);break;case sort:sort_contact(&con);break;case quit:destroy_contact(&con);printf("Exiting Contacts...\n");break;default:printf("You entered the wrong number, please re-enter it.\n");break;}} while (choice);printf("Exited Contacts.\n");}int main()
{test();return 0;
}

四、通讯录功能函数

1.全代码

#include"contact.h"void menu2()
{system("cls");printf("1> name \t 2> age\n");printf("3> sex \t 4> address\n");printf("5> phone\n");printf("Please select:");
}//动态
void init_contact(contact* con)
{assert(con);// per    sz ContactMaxcon->sz = 0;person* p = (person*)calloc(Max, sizeof(person));if (p == NULL){perror("init_contact::calloc");return;}con->per = p;con->ContactMax = Max;
}void tune(contact* con)
{if (con->sz == con->ContactMax){person *p = (person *)realloc(con->per, (con->ContactMax + Max) * sizeof(person));if (p == NULL){perror("tune::realloc");return;}con->per = p;con->ContactMax += Max;}
}//动态开辟
void increase_contact(contact* con)
{assert(con);//检测当前通讯录是否需要增容tune(con);printf("name:");scanf("%s", &(con->per[con->sz].name));printf("age:");scanf("%u", &(con->per[con->sz].age));printf("sex:");scanf("%s", &(con->per[con->sz].sex));printf("address:");scanf("%s", &(con->per[con->sz].address));printf("phone:");scanf("%s", &(con->per[con->sz].phone));(con->sz)++;
}void delete_contact(contact* con)
{assert(con);menu2();size_t choice = 0;size_t result = 0;while (1){scanf("%u", &choice);if (choice <= 5 && choice >= 1){result = find1(&con, choice);break;}else{printf("Your input is incorrect, please re-enter it:");}}if (result != -1){char true[5] = { 0 };printf("Are you sure you want to delete %s's information?", &con->per[result].name);printf("yes/no:");scanf("%s", &true);if (!strcmp(true, "yes")){if ( con->sz ){memmove(con->per[result].name, con->per[(con->sz) - 1].name, sizeof(con->per[0]));}else{memset(con->per[result].name, 0, sizeof(con->per[0]));}(con->sz)--;printf("The deletion was successful, thanks for using!\n");          }else{printf("Delete failed, please try again!\n");}}else{printf("Delete failed, please try again!\n");}
}int find1(const contact** con, size_t choice)
{assert(con);size_t i = 0;char sample1[30] = { 0 };size_t sample2 = 0;printf("Please enter:");switch (choice){case 1:case 3:case 4:case 5:scanf("%s", &sample1);break;case 2:scanf("%u", &sample2);break;}switch (choice){case 1:while (i < (*con)->sz){if (!strcmp(sample1, (*con)->per[i].name)){return i;}else{i++;}}break;case 3:while (i < (*con)->sz){if (!strcmp(sample1, (*con)->per[i].sex)){return i;}else{i++;}}break;case 4:while (i < (*con)->sz){if (!strcmp(sample1, (*con)->per[i].address)){return i;}else{i++;}}break;case 5:while (i < (*con)->sz){if (!strcmp(sample1, (*con)->per[i].phone)){return i;}else{i++;}}break;case 2:while (i < (*con)->sz){if (sample2 == (*con)->per[i].age){return i;}else{i++;}}break;}return -1;
}void find_contact(const contact* con)
{assert(con);menu2();size_t choice = 0;size_t result = 0;while (1){scanf("%u", &choice);if (choice <= 5 && choice >= 1){result = find1(&con, choice);break;}else{printf("Your input is incorrect, please re-enter it:");}}if (result != -1){printf("Found, the basic information of the contact is:");printf("name:%-20s\tage:%-4d\tsex:%-5s\taddress:%-30s\tphone:%-12s\n",con->per[result].name,con->per[result].age,con->per[result].sex,con->per[result].address,con->per[result].phone);}else{printf("Didn't find it!\n");}}void revise_contact(contact* con)
{assert(con);menu2();size_t choice = 0;size_t result = 0;while (1){scanf("%u", &choice);if (choice <= 5 && choice >= 1){result = find1(&con, choice);break;}else{printf("Your input is incorrect, please re-enter it:");}}if (result != -1){char true[5] = { 0 };printf("Are you sure you want to revise %s's information?", &con->per[result].name);printf("yes/no:");scanf("%s", &true);if (!strcmp(true, "yes")){menu2();printf("Please enter the option you want to modify:");scanf("%u", &choice);char sample1[30] = { 0 };size_t sample2 = 0;printf("Please enter:");switch (choice){case 1:case 3:case 4:case 5:scanf("%s", &sample1);break;case 2:scanf("%u", &sample2);break;}switch (choice){case 1:memmove(con->per[result].name, sample1, sizeof(con->per[0].name));break;case 3:memmove(con->per[result].name, sample1, sizeof(con->per[0].sex));break;case 4:memmove(con->per[result].name, sample1, sizeof(con->per[0].address));break;case 5:memmove(con->per[result].name, sample1, sizeof(con->per[0].phone));break;case 2:con->per[result].age = sample2;break;}printf("The modification is complete, thanks for using!\n");}else{printf("Revise failed, please try again!\n");}}else{printf("Revise failed, please try again!\n");}
}void show_contact(const contact* con)
{assert(con);if ( con->sz ){size_t i = 0;for (; i < (con->sz); i++){printf("name:%-20s\tage:%-4d\tsex:%-5s\taddress:%-30s\tphone:%-12s\n",con->per[i].name, con->per[i].age, con->per[i].sex,con->per[i].address, con->per[i].phone);}}else{printf("There is no contact information in the address book!\n");}
}int cmp_char(const void* str1, const void* str2)
{return strcmp(((person*)str1)->name, ((person*)str2)->name);
}void sort_contact(contact* con)
{qsort(con -> per[0].name, con -> sz, sizeof(con -> per[0]), cmp_char);
}void destroy_contact(contact* con)
{free(con->per);con->per = NULL;con->ContactMax = 0;con->sz = 0;con = NULL;
}

2.增加联系人

使用realloc()调整通讯录大小。

联系人信息图为:

void tune(contact* con)
{if (con->sz == con->ContactMax){person *p = (person *)realloc(con->per, (con->ContactMax + Max) * sizeof(person));if (p == NULL){perror("tune::realloc");return;}con->per = p;con->ContactMax += Max;}
}//动态开辟
void increase_contact(contact* con)
{assert(con);//检测当前通讯录是否需要增容tune(con);printf("name:");scanf("%s", &(con->per[con->sz].name));printf("age:");scanf("%u", &(con->per[con->sz].age));printf("sex:");scanf("%s", &(con->per[con->sz].sex));printf("address:");scanf("%s", &(con->per[con->sz].address));printf("phone:");scanf("%s", &(con->per[con->sz].phone));(con->sz)++;
}

3.删除联系人

通过选择联系人的某种信息(例如姓名、年龄)来查找需要删除的联系人,找到之后确认删除该联系人。

例如:

void delete_contact(contact* con)
{assert(con);menu2();size_t choice = 0;size_t result = 0;while (1){scanf("%u", &choice);if (choice <= 5 && choice >= 1){result = find1(&con, choice);break;}else{printf("Your input is incorrect, please re-enter it:");}}if (result != -1){char true[5] = { 0 };printf("Are you sure you want to delete %s's information?", &con->per[result].name);printf("yes/no:");scanf("%s", &true);if (!strcmp(true, "yes")){if ( con->sz ){memmove(con->per[result].name, con->per[(con->sz) - 1].name, sizeof(con->per[0]));}else{memset(con->per[result].name, 0, sizeof(con->per[0]));}(con->sz)--;printf("The deletion was successful, thanks for using!\n");          }else{printf("Delete failed, please try again!\n");}}else{printf("Delete failed, please try again!\n");}
}

4.查找联系人

通过联系人基础信息查找联系人。

int find1(const contact** con, size_t choice)
{assert(con);size_t i = 0;char sample1[30] = { 0 };size_t sample2 = 0;printf("Please enter:");switch (choice){case 1:case 3:case 4:case 5:scanf("%s", &sample1);break;case 2:scanf("%u", &sample2);break;}switch (choice){case 1:while (i < (*con)->sz){if (!strcmp(sample1, (*con)->per[i].name)){return i;}else{i++;}}break;case 3:while (i < (*con)->sz){if (!strcmp(sample1, (*con)->per[i].sex)){return i;}else{i++;}}break;case 4:while (i < (*con)->sz){if (!strcmp(sample1, (*con)->per[i].address)){return i;}else{i++;}}break;case 5:while (i < (*con)->sz){if (!strcmp(sample1, (*con)->per[i].phone)){return i;}else{i++;}}break;case 2:while (i < (*con)->sz){if (sample2 == (*con)->per[i].age){return i;}else{i++;}}break;}return -1;
}void find_contact(const contact* con)
{assert(con);menu2();size_t choice = 0;size_t result = 0;while (1){scanf("%u", &choice);if (choice <= 5 && choice >= 1){result = find1(&con, choice);break;}else{printf("Your input is incorrect, please re-enter it:");}}if (result != -1){printf("Found, the basic information of the contact is:");printf("name:%-20s\tage:%-4d\tsex:%-5s\taddress:%-30s\tphone:%-12s\n",con->per[result].name,con->per[result].age,con->per[result].sex,con->per[result].address,con->per[result].phone);}else{printf("Didn't find it!\n");}}

5.修改联系人

先查找,再修改。

可以修改联系人的任一信息。

void revise_contact(contact* con)
{assert(con);menu2();size_t choice = 0;size_t result = 0;while (1){scanf("%u", &choice);if (choice <= 5 && choice >= 1){result = find1(&con, choice);break;}else{printf("Your input is incorrect, please re-enter it:");}}if (result != -1){char true[5] = { 0 };printf("Are you sure you want to revise %s's information?", &con->per[result].name);printf("yes/no:");scanf("%s", &true);if (!strcmp(true, "yes")){menu2();printf("Please enter the option you want to modify:");scanf("%u", &choice);char sample1[30] = { 0 };size_t sample2 = 0;printf("Please enter:");switch (choice){case 1:case 3:case 4:case 5:scanf("%s", &sample1);break;case 2:scanf("%u", &sample2);break;}switch (choice){case 1:memmove(con->per[result].name, sample1, sizeof(con->per[0].name));break;case 3:memmove(con->per[result].name, sample1, sizeof(con->per[0].sex));break;case 4:memmove(con->per[result].name, sample1, sizeof(con->per[0].address));break;case 5:memmove(con->per[result].name, sample1, sizeof(con->per[0].phone));break;case 2:con->per[result].age = sample2;break;}printf("The modification is complete, thanks for using!\n");}else{printf("Revise failed, please try again!\n");}}else{printf("Revise failed, please try again!\n");}
}

6.展示联系人

展示所有联系人及其所有信息。

void show_contact(const contact* con)
{assert(con);if ( con->sz ){size_t i = 0;for (; i < (con->sz); i++){printf("name:%-20s\tage:%-4d\tsex:%-5s\taddress:%-30s\tphone:%-12s\n",con->per[i].name, con->per[i].age, con->per[i].sex,con->per[i].address, con->per[i].phone);}}else{printf("There is no contact information in the address book!\n");}
}

7.清空联系人

又名初始化通讯录。

重新向内存申请一片空间,存储联系人信息。

void init_contact(contact* con)
{assert(con);// per    sz ContactMaxcon->sz = 0;person* p = (person*)calloc(Max, sizeof(person));if (p == NULL){perror("init_contact::calloc");return;}con->per = p;con->ContactMax = Max;
}

8.退出通讯录

通过free()释放内存栈区的空间,避免内存泄露。

void destroy_contact(contact* con)
{free(con->per);con->per = NULL;con->ContactMax = 0;con->sz = 0;con = NULL;
}

总结

在使用完内存函数之后,一定一定要记得释放空间哦~

上述代码展示就是整个动态通讯录的全部啦,如果你有兴趣想要了解,可以通过C_Ccpp/C_study/contact at main · Yjun6/C_Ccpp (github.com)找到它们。

相关文章:

C语言/动态通讯录

本文使用了malloc、realloc、calloc等和内存开辟有关的函数。 文章目录 前言 二、头文件 三、主界面 四、通讯录功能函数 1.全代码 2.增加联系人 3.删除联系人 4.查找联系人 5.修改联系人 6.展示联系人 7.清空联系人 8.退出通讯录 总结 前言 为了使用通讯录时&#xff0c;可以…...

我用Compose做了一个地图轮子OmniMap

一、前言 半年前&#xff0c;我发布过一篇介绍&#xff1a;Compose里面如何使用地图&#xff0c;比如高德地图 的文章&#xff0c;原本是没有想造什么轮子的✍️ 闲来无事&#xff0c;有一天看到了评论区留言让我把源码地址分享出来&#xff0c;我感觉我太懒了&#xff0c;后来…...

STM32之SPI

SPISPI介绍SPI是串行外设接口(Serial Peripherallnterface)的缩写&#xff0c;是一种高速的&#xff0c;全双工&#xff0c;同步的通信总线&#xff0c;并且在芯片的管脚上只占用四根线&#xff0c;节约了芯片的管脚&#xff0c;同时为PCB的布局上节省空间&#xff0c;提供方便…...

02 深度学习环境搭建

1、查看对应版本关系 详细见&#xff1a;https://blog.csdn.net/qq_41946216/article/details/129476095?spm1001.2014.3001.5501此案例环境使用 CUDA 11.7、Pytouch1.12.1、Miniconda3_py38(含Python3.8) 2. 安装Anaconda 或 Miniconda 本案例重点一为Miniconda准 2.1 安…...

PHP导入大量CSV数据的方法分享

/** * @description 迭代器读取csv文件 * @param $strCsvPath * @return \Generator */ public static function readPathCsvFile($strCsvPath) { if ($handle = fopen($strCsvPath, r)) { while (!feof($handle)) { yield fgetcsv($handle); } …...

代码看不懂?ChatGPT 帮你解释,详细到爆!

偷个懒&#xff0c;用ChatGPT 帮我写段生物信息代码如果 ChatGPT 给出的的代码不太完善&#xff0c;如何请他一步步改好&#xff1f;网上看到一段代码&#xff0c;不知道是什么含义&#xff1f;输入 ChatGPT 帮我们解释下。生信宝典 1: 下面是一段 Linux 代码&#xff0c;请帮…...

【MyBatis】篇三.自定义映射resultMap和动态SQL

MyBatis整理 篇一.MyBatis环境搭建与增删改查 篇二.MyBatis查询与特殊SQL 篇三.自定义映射resultMap和动态SQL 篇四.MyBatis缓存和逆向工程 文章目录1、自定义映射P1:测试数据准备P2:字段和属性的映射关系P3:多对一的映射关系P4:一对多的映射关系2、动态SQL2.1 IF标签2.2 w…...

什么是API?(详细解说)

编程资料时经常会看到API这个名词&#xff0c;网上各种高大上的解释估计放倒了一批初学者。初学者看到下面这一段话可能就有点头痛了。 API&#xff08;Application Programming Interface,应用程序编程接口&#xff09;是一些预先定义的函数&#xff0c;目的是提供应用程序与开…...

比cat更好用的命令!

大家好&#xff0c;我是良许。 作为程序员&#xff0c;大家一定对 cat 这个命令不陌生。它主要的功能就是用来显示文本文件的具体内容。 但 cat 命令两个很重大的缺陷&#xff1a;1. 不能语法高亮输出&#xff1b;2. 文本太长的话无法翻页输出。正是这两个不足&#xff0c;使…...

MySQL、HBase、ElasticSearch三者对比

1、概念介绍 MySQL&#xff1a;关系型数据库&#xff0c;主要面向OLTP&#xff0c;支持事务&#xff0c;支持二级索引&#xff0c;支持sql&#xff0c;支持主从、Group Replication架构模型&#xff08;本文全部以Innodb为例&#xff0c;不涉及别的存储引擎&#xff09;。 HBas…...

Vue+ElementUI+Vuex购物车

最完整最能理解的Vuex版本的购物车购物车是最经典的小案例。Vuex代码&#xff1a;import Vue from vue import Vuex from vuex import $http from ../request/http Vue.use(Vuex)const store new Vuex.Store({state:{shopList:[],},mutations:{setShopCarList(state,payload)…...

Android 录屏 实现

https://lixiaogang03.github.io/2021/11/02/Android-%E5%BD%95%E5%B1%8F/ https://xie.infoq.cn/article/dd40cd5d753c896225063f696 视频地址&#xff1a; https://time.geekbang.org/dailylesson/detail/100056832 概述 在视频会议、线上课堂、游戏直播等场景下&#x…...

【CSAPP】家庭作业2.55~2.76

文章目录2.55*2.56*2.57*2.58**2.59**2.60**位级整数编码规则2.61**2.62***2.63***2.64*2.65****2.66***2.67**2.68**2.69***2.70**2.71*2.72**2.73**2.74**2.75***2.76*2.55* 问&#xff1a;在你能访问的不同的机器上&#xff0c;编译show_bytes.c并运行代码&#xff0c;确定…...

Python操作MySQL数据库详细案例

Python操作MySQL数据库详细案例一、前言二、数据准备三、建立数据库四、处理和上传数据五、下载数据六、完整项目数据和代码一、前言 本文通过案例讲解如何使用Python操作MySQL数据库。具体任务为&#xff1a;假设你已经了解MySQL和知识图谱标注工具Brat&#xff0c;将Brat标注…...

MicroBlaze系列教程(8):AXI_CAN的使用

文章目录 @[toc]CAN总线概述AXI_CAN简介MicroBlaze硬件配置常用函数使用示例波形实测参考资料工程下载本文是Xilinx MicroBlaze系列教程的第8篇文章。 CAN总线概述 **CAN(Controller Area Network)**是 ISO 国际标准化的串行通信协议,是由德国博世(BOSCH)公司在20世纪80年代…...

网络安全领域中八大类CISP证书

CISP​注册信息安全专业人员 注册信息安全专业人员&#xff08;Certified Information Security Professional&#xff09;&#xff0c;是经中国信息安全产品测评认证中心实施的国家认证&#xff0c;对信息安全人员执业资质的认可。该证书是面向信息安全企业、信息安全咨询服务…...

stm32学习笔记-5EXIT外部中断

5 EXIT外部中断 [toc] 注&#xff1a;笔记主要参考B站 江科大自化协 教学视频“STM32入门教程-2023持续更新中”。 注&#xff1a;工程及代码文件放在了本人的Github仓库。 5.1 STM32中断系统 图5-1 中断及中断嵌套示意图 中断 是指在主程序运行过程中&#xff0c;出现了特定…...

MySQL Workbench 图形化界面工具

Workbench 介绍 MySQL官方提供了一款免费的图形工具——MySQL Workbench&#xff0c;它是一款功能强大且易于使用的数据库设计、管理和开发工具&#xff0c;总之&#xff0c;MySQL Workbench是一款非常好用的MySQL图形工具&#xff0c;可以满足大多数MySQL用户的需求。 目录 W…...

雪花算法(SnowFlake)

简介现在的服务基本是分布式、微服务形式的&#xff0c;而且大数据量也导致分库分表的产生&#xff0c;对于水平分表就需要保证表中 id 的全局唯一性。对于 MySQL 而言&#xff0c;一个表中的主键 id 一般使用自增的方式&#xff0c;但是如果进行水平分表之后&#xff0c;多个表…...

Linux防火墙

一、Linux防火墙Linux的防火墙体系主要在网络层&#xff0c;针对TCP/IP数据包实施过滤和限制&#xff0c;属于典型的包过滤防火墙&#xff08;或称为网络层防火墙&#xff09;。Linux系统的防火墙体系基于内核编码实现&#xff0c;具有非常稳定的性能和极高的效率&#xff0c;因…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止

<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet&#xff1a; https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...

06 Deep learning神经网络编程基础 激活函数 --吴恩达

深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...

RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)

RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发&#xff0c;后来由Pivotal Software Inc.&#xff08;现为VMware子公司&#xff09;接管。RabbitMQ 是一个开源的消息代理和队列服务器&#xff0c;用 Erlang 语言编写。广泛应用于各种分布…...

ZYNQ学习记录FPGA(一)ZYNQ简介

一、知识准备 1.一些术语,缩写和概念&#xff1a; 1&#xff09;ZYNQ全称&#xff1a;ZYNQ7000 All Pgrammable SoC 2&#xff09;SoC:system on chips(片上系统)&#xff0c;对比集成电路的SoB&#xff08;system on board&#xff09; 3&#xff09;ARM&#xff1a;处理器…...

sshd代码修改banner

sshd服务连接之后会收到字符串&#xff1a; SSH-2.0-OpenSSH_9.5 容易被hacker识别此服务为sshd服务。 是否可以通过修改此banner达到让人无法识别此服务的目的呢&#xff1f; 不能。因为这是写的SSH的协议中的。 也就是协议规定了banner必须这么写。 SSH- 开头&#xff0c…...

Appium下载安装配置保姆教程(图文详解)

目录 一、Appium软件介绍 1.特点 2.工作原理 3.应用场景 二、环境准备 安装 Node.js 安装 Appium 安装 JDK 安装 Android SDK 安装Python及依赖包 三、安装教程 1.Node.js安装 1.1.下载Node 1.2.安装程序 1.3.配置npm仓储和缓存 1.4. 配置环境 1.5.测试Node.j…...

Copilot for Xcode (iOS的 AI辅助编程)

Copilot for Xcode 简介Copilot下载与安装 体验环境要求下载最新的安装包安装登录系统权限设置 AI辅助编程生成注释代码补全简单需求代码生成辅助编程行间代码生成注释联想 代码生成 总结 简介 尝试使用了Copilot&#xff0c;它能根据上下文补全代码&#xff0c;快速生成常用…...