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

C语言 通讯录管理 完整代码

这份代码,是我从网上找的。目前是能运行。我正在读。有些不懂的地方,等下再记录下来。
有些地方的命名,还需要重新写一下。

比如:

PersonInfo* info = &address_book->all_address[address_book->size];

应该改为:

PersonInfo* info = &(address_book->all_address[address_book->size]);

就是加上一个括号。更清晰一些。

效果图:

#include<stdio.h>
#include<string.h>#define Max_SIZE 50 //定义通讯录的大小typedef struct PersonInfo {char name[100];char phone[100];
}PersonInfo;typedef struct AddressBook {PersonInfo all_address[Max_SIZE];int size;
}AddressBook;
//size 的含义是:
//数组 all_address 下标范围在 [0,size) 内的元素是有意义的
//                            [size, 200) 是我们没有用到的//初始化
void init(AddressBook* address_book) {address_book->size = 0;//尽量少用 magic number(不明含义的数字)for (int i = 0; i < Max_SIZE; i++) {strcpy(address_book->all_address->name, " ");strcpy(address_book->all_address->phone, " ");}}int Menu(void) {printf("======================\n");printf("***     0.退出     ***\n");printf("***  1.新增联系人  ***\n");printf("***  2.删除联系人  ***\n");printf("***  3.查找联系人  ***\n");printf("***  4.修改联系人  ***\n");printf("***  5.打印联系人  ***\n");printf("***  6.清除联系人  ***\n");printf("***  7.排序联系人  ***\n");printf("======================\n");printf("请输入你的选择:");int choice;scanf("%d", &choice);return choice;
}void AddPersonInfo(AddressBook* address_book) {printf("新增联系人\n");if (address_book->size >= Max_SIZE) {printf("通讯录已满,请先清除!\n");return;//虽然函数类型是 void 但是也是可以用 return 滴}PersonInfo* info = &address_book->all_address[address_book->size];printf("请输入联系人姓名:");scanf("%s", info->name);printf("请输入联系人电话:");scanf("%s", info->phone);address_book->size++;
}void DelPersonInfo(AddressBook* address_book) {//删除的方法很多,可以根据姓名,电话,序号等等来删除,//这里我们就用我个人比较常用的 搜索名字的删除方法char search_name[100] = { 0 };printf("删除联系人\n");printf("请输入联系人姓名:");scanf("%s", search_name);int name_exist = FindName(address_book, search_name);//这里注意 FindName 返回值设定,要被删除的元素下标可能是 0,这种情况下会返回 0 if (name_exist == -1) {printf("该联系人不存在!\n");return;}//删除了相同姓名的第一个后,继续寻找改名字,如果找到了,重复上面的操作,如果没找到,退出循环//相同的姓名的情况比较复杂,在修改,查找,排序等等场景都会带来麻烦,//而且平时你的通讯录中难道会将两个相同姓名的人的备注写成一样的吗?//所以,我仅仅在删除功能中实现一种针对相同姓名的情况的设计思路,后面的其他功能默认没有重复姓名的情况。while (name_exist != -1) {//将 all_address 数组的最后一个元素赋值给要删除的元素,完成删除//结构体类型是可以直接赋值的address_book->all_address[name_exist] = address_book->all_address[address_book->size - 1];address_book->size--;name_exist = FindName(address_book, search_name);}printf("删除成功!\n");}int FindName(AddressBook* address_book, char search_name[100]) {for (int i = 0; i < address_book->size; i++) {//找到返回数组下标if (strcmp(address_book->all_address->name, search_name) == 0) {return i;}}//没有找到,返回 -1return -1;
}void FindPersonInfo(AddressBook* address_book) {char search_name[100] = { 0 };//搜索人的方式也很多,我们这里用搜索名字的方法printf("更新联系人\n");printf("请输入人名:");scanf("%s", search_name);for (int i = 0; i < address_book->size; i++) {PersonInfo* info = &address_book->all_address[i];// 创建一个 PersonInfo 类型的变量简化程序,不然下面的姓名访问就太长了if (strcmp(info->name, search_name) == 0) {printf("[%d] %s  %s\n", i, info->name, info->phone);}}}void ModifyPersonInfo(AddressBook* address_book) {char search_name[100] = { 0 };int isjump = 1;printf("删除联系人\n");printf("请输入联系人姓名:");scanf("%s", search_name);int name_exist = FindName(address_book, search_name);if (name_exist == -1) {printf("该联系人不存在!\n");return;}//优化以下用户的体验printf("请输入新的姓名,输入 0 跳过:");scanf("%d", &isjump);if (isjump) {scanf("%s", address_book->all_address[name_exist].name);}printf("请输入新的电话,输入 0 跳过:");scanf("%d", &isjump);if (isjump) {scanf("%s", address_book->all_address[name_exist].phone);}printf("更新成功!\n");}void PrintPersonInfo(AddressBook* address_book) {PersonInfo* info;if (address_book->size == 0) {printf("当前没有联系人!\n");return;}printf("所有联系人信息如下:\n");for (int i = 0; i < address_book->size; i++) {info = &address_book->all_address[i];printf("[%2d]%4s  %s\n", i, info->name, info->phone);}
}void ClearPersonInfo(AddressBook* address_book) {//清除所有信息是一种 危险的行为,我们最好让用户确认一次//相比你应该在自己的手机上回复过出厂设置,系统应该会让你确认不止一次!int is_continue = 0;printf("清除所有联系人,你确定吗?输入 0 继续: ");scanf("%d", &is_continue);if(is_continue == 0) {//将 size 置为 0 即可,不过你也可以将数组的每个元素都进行重置address_book->size = 0;}printf("清除完成!\n");
}void SortPersonInfo(AddressBook* address_book) {printf("排序通讯录\n");for (int i = 0; i < address_book->size - 1; i++) {for (int j = 0; j < address_book->size - 1 - i; j++) {PersonInfo* info = &address_book->all_address[j];PersonInfo* info_next = &address_book->all_address[j + 1];//简单的用 strcmp 进行排序,不过排序的行为感觉是“未定义”的,//看着有规律,但再多试试会发现很多情况并没有规律。//也还有很多可以排血的函数。比如:strcoll,wcsscoll,wcscmp 这些只要你能弄懂,我想你也可以用。//或者有其他更好的实现办法,但这并不是我们在这里的重点。if (strcmp(info->name, info_next) > 0) {PersonInfo tmp;tmp = *info;*info = *info_next;*info_next = tmp;}}}printf("排序成功!\n");
}int main(int argc, char* argv[]) {AddressBook address_book;//声明一个函数指针类型typedef void (*Func)(AddressBook*);Func func_table[] = {NULL,AddPersonInfo,DelPersonInfo,FindPersonInfo,ModifyPersonInfo,PrintPersonInfo,ClearPersonInfo,SortPersonInfo,};//或者你也可以这么做://声明一个函数类型://typedef void (Func)(AddressBook*);//我们用的是指针数组,数组类型必须是指针类型,所以应该加上 * //Func* func_table[] = {//NULL,//AddPersonInfo,//DelPersonInfo,//FindPersonInfo,//ModifyPersonInfo,//PrintPersonInfo,//ClearPersonInfo,//SortPersonInfo,//}; init(&address_book);while (1) {int choice = Menu();if (choice < 0 || choice > 7) {printf("输入错误!\n");continue;}if (choice == 0) {printf("再见!\n");break;}func_table[choice](&address_book);}return 0;
}

相关文章:

C语言 通讯录管理 完整代码

这份代码&#xff0c;是我从网上找的。目前是能运行。我正在读。有些不懂的地方&#xff0c;等下再记录下来。 有些地方的命名&#xff0c;还需要重新写一下。 比如: PersonInfo* info &address_book->all_address[address_book->size]; 应该改为&#xff1a; Perso…...

2024北京国际智能工厂及自动化展览会亮点前瞻

随着“工业创新&#xff0c;智造未来”的浪潮席卷而来&#xff0c;2024年度北京国际智能工厂及自动化与工业装配展览会定于8月1日至3日在中国国际展览中心&#xff08;顺义新馆&#xff09;盛大开幕。本次展会汇聚了智能制造与自动化技术的最新成果&#xff0c;通过三展联动的创…...

《网络安全等级保护制度详解》

网络安全等级保护制度是我国网络安全领域的一项重要制度&#xff0c;旨在保障网络安全&#xff0c;维护国家安全、社会秩序和公共利益。 网络安全等级保护制度主要包含以下几个关键方面&#xff1a; 等级划分 根据信息系统在国家安全、经济建设、社会生活中的重要程度&#xff…...

使用Wanderboat AI 来规划到巴黎的旅行计划

​ Wanderboat AI 平台是一个由 GPT-4 驱动的智能旅行规划工具&#xff0c;旨在通过自然对话和多模式互动&#xff0c;为用户提供个性化的旅行行程。以下是该平台的架构和使用方法&#xff1a; 平台架构 GPT-4 驱动&#xff1a;平台利用 GPT-4 的强大自然语言处理能力&#x…...

基于YOLO8的目标检测系统:开启智能视觉识别之旅

文章目录 在线体验快速开始一、项目介绍篇1.1 YOLO81.2 ultralytics1.3 模块介绍1.3.1 scan_task1.3.2 scan_taskflow.py1.3.3 target_dec_app.py 二、核心代码介绍篇2.1 target_dec_app.py2.2 scan_taskflow.py 三、结语 在线体验 基于YOLO8的目标检测系统 基于opencv的摄像头…...

实验07 接口测试postman

目录 知识点 1 接口测试概念 1.1为什么要做接口测试 1.2接口测试的优点 1.3接口测试概念 1.4接口测试原理和目的 2 接口测试内容 2.1测什么 2.1.1单一接口 2.1.2组合接口 2.1.3结构检查 2.1.4调用方式 2.1.5参数格式校验 2.1.6返回结果 2.2四大块 2.2.1功能逻辑…...

C++常用但难记的语法

模板函数的声明和定义必须在同一个文件中。 C中每一个对象所占用的空间大小&#xff0c;是在编译的时候就确定的&#xff0c;在模板类没有真正的被使用之前&#xff0c;编译器是无法知道&#xff0c;模板类中使用模板类型的对象的所占用的空间的大小的。只有模板被真正使用的时…...

Qt 快速保存配置的方法

Qt 快速保存配置的方法 一、概述二、代码1. QFileHelper.cpp2. QSettingHelper.cpp 三、使用 一、概述 这里分享一下&#xff0c;Qt界面开发时&#xff0c;快速保存界面上一些参数配置的方法。 因为我在做实验的时候&#xff0c;界面上可能涉及到很多参数的配置&#xff0c;我…...

RKE部署k8s

移除docker&#xff08;非必要&#xff09; rm -rf /etc/docker rm -rf /run/docker rm -rf /var/lib/dockershim rm -rf /var/lib/docker yum list installed | grep docker yum remove ***rke部署k8s集群 cat > /etc/sysctl.conf << EFO net.ipv4.ip_forward 1 n…...

从0开始的STM32HAL库学习8

PWM控制舵机 配置环境 1. 选择TIM2时钟 2.选择内部时钟模式&#xff0c;打开通道二 3.分频系数PSC:72-1 自动重装寄存器ARR:20000-1 输出比较寄存器 CCR:500~2500( 后面可调整 ) 脉冲选择500后期可以改 编辑代码 调用启动函数 HAL_TIM_PWM_Start(&htim2,TIM_CHANN…...

微信小程序数组绑定使用案例(一)

微信小程序数组绑定案例&#xff0c;修改数组中的值 1.Wxml 代码 <view class"list"><view class"item {{item.ischeck?active:}}" wx:for"{{list}}"><view class"title">{{item.name}} <text>({{item.id}…...

Kudu节点数规划

作者&#xff1a;南墨 一、概述 由于Kudu是Hadoop生态的一部分&#xff08;虽然它不依赖于Hadoop生态系统&#xff09;&#xff0c;因此大多数实际应用场景需要的不仅仅是Kudu&#xff1b;为了输入数据&#xff0c;可能需要Kafka、StreamSets或Spark Streaming&#xff1b;对…...

flutter 充电气泡

前言&#xff1a; 之前一直看到 有手机充电的时候 有气泡从Type-C 的位置冒泡上来 慢慢上移&#xff0c; 然后和上面的圆圈 会和&#xff0c;感觉还是挺好看的。今天试了下用 Flutter 实现了一版本。大致效果如下&#xff0c;而且气泡 和 气泡直接还可以粘黏 实现原理&#xff…...

【C++】deque以及优先级队列

容器适配器 deque的介绍deque的原理介绍 priority_queue的介绍与使用priority_queue的介绍priority_queue的使用constructor&#xff08;构造函数&#xff09;emptypushpoptopsize priority_queue的模拟实现 仿函数何为适配器容器适配器deque的缺陷选择deque作为适配器的理由ST…...

手机如何播放电脑的声音?

准备工具&#xff1a; 有线耳机&#xff0c;手机&#xff0c;电脑&#xff0c;远控软件 1.有线耳机插电脑上 2.电脑安装pc版远控软件&#xff0c;手机安装手机端控制版远控软件 3.手机控制电脑开启声音控制 用手机控制电脑后&#xff0c;打开声音控制&#xff0c;电脑播放视频…...

系统架构设计师教程 第3章 信息系统基础知识-3.6 办公自动化系统(OAS)-解读

系统架构设计师教程 第3章 信息系统基础知识-3.6 办公自动化系统&#xff08;OAS&#xff09; 3.6.1 办公自动化系统的概念3.6.1.1 办公活动3.6.1.1 办公自动化的概念 3.6.2 办公自动化系统的功能3.6.2.1 事务处理3.6.2.1.1 单机系统3.6.2.1.2 多机系统 3.6.2.2 信息管理3.6.2.…...

解决Element UI 表格组件懒加载数据刷新问题

一、问题描述 element ui的table组件设置成懒加载时&#xff0c;遇到数据表格需要更新、删除等操作&#xff0c;子节点不会自动更新。 二、解决思路 刷新数据&#xff0c;就是重新调用load&#xff08;&#xff09;&#xff0c;通过map记录已展开的节点&#xff0c;需要刷新…...

【系统架构设计 每日一问】二 MySql主从复制延迟可能是什么原因,怎么解决

主从复制的架构设计如下图所示&#xff1a; 同步原理 具体到数据库之间是通过binlog和复制线程操作的&#xff1a; Master的更新事件(update、insert、delete)会按照顺序写入bin-log中。当Slave连接到Master的后,Master机器会为Slave开启&#xff0c;binlog dump线程,该线程…...

Ubuntu Grub引导优化

配置文件 sudo vim /etc/default/grub修改参数 引导菜单等待时间 GRUB_TIMEOUT3自动引导上次选择的系统 如果安装了双系统或多系统&#xff0c;可以考虑配置此参数。 # 此参数默认值为0&#xff0c;引导第一个引导项 GRUB_DEFAULTsaved# 此参数默认没有&#xff0c;需要手…...

第3关 -- Git 基础知识

任务1: 破冰活动&#xff1a;自我介绍 任务2: 实践项目&#xff1a;构建个人项目 MeiHuaYiShu...

【杂谈】-递归进化:人工智能的自我改进与监管挑战

递归进化&#xff1a;人工智能的自我改进与监管挑战 文章目录 递归进化&#xff1a;人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管&#xff1f;3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

AtCoder 第409​场初级竞赛 A~E题解

A Conflict 【题目链接】 原题链接&#xff1a;A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串&#xff0c;只有在同时为 o 时输出 Yes 并结束程序&#xff0c;否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具&#xff0c;可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板&#xff0c;允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板&#xff0c;并通…...

AI病理诊断七剑下天山,医疗未来触手可及

一、病理诊断困局&#xff1a;刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断"&#xff0c;医生需通过显微镜观察组织切片&#xff0c;在细胞迷宫中捕捉癌变信号。某省病理质控报告显示&#xff0c;基层医院误诊率达12%-15%&#xff0c;专家会诊…...

JS手写代码篇----使用Promise封装AJAX请求

15、使用Promise封装AJAX请求 promise就有reject和resolve了&#xff0c;就不必写成功和失败的回调函数了 const BASEURL ./手写ajax/test.jsonfunction promiseAjax() {return new Promise((resolve, reject) > {const xhr new XMLHttpRequest();xhr.open("get&quo…...

iview框架主题色的应用

1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题&#xff0c;无需引入&#xff0c;直接可…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...