当前位置: 首页 > 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...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统&#xff0c;智慧工地全套源码&#xff0c;java版智慧工地源码&#xff0c;支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求&#xff0c;提供“平台网络终端”的整体解决方案&#xff0c;提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

【Linux】C语言执行shell指令

在C语言中执行Shell指令 在C语言中&#xff0c;有几种方法可以执行Shell指令&#xff1a; 1. 使用system()函数 这是最简单的方法&#xff0c;包含在stdlib.h头文件中&#xff1a; #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

Linux-07 ubuntu 的 chrome 启动不了

文章目录 问题原因解决步骤一、卸载旧版chrome二、重新安装chorme三、启动不了&#xff0c;报错如下四、启动不了&#xff0c;解决如下 总结 问题原因 在应用中可以看到chrome&#xff0c;但是打不开(说明&#xff1a;原来的ubuntu系统出问题了&#xff0c;这个是备用的硬盘&a…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

聊一聊接口测试的意义有哪些?

目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开&#xff0c;首…...

MySQL的pymysql操作

本章是MySQL的最后一章&#xff0c;MySQL到此完结&#xff0c;下一站Hadoop&#xff01;&#xff01;&#xff01; 这章很简单&#xff0c;完整代码在最后&#xff0c;详细讲解之前python课程里面也有&#xff0c;感兴趣的可以往前找一下 一、查询操作 我们需要打开pycharm …...

[USACO23FEB] Bakery S

题目描述 Bessie 开了一家面包店! 在她的面包店里&#xff0c;Bessie 有一个烤箱&#xff0c;可以在 t C t_C tC​ 的时间内生产一块饼干或在 t M t_M tM​ 单位时间内生产一块松糕。 ( 1 ≤ t C , t M ≤ 10 9 ) (1 \le t_C,t_M \le 10^9) (1≤tC​,tM​≤109)。由于空间…...