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

【C语言】通讯录的实现(静态版)

【C语言】通讯录的实现(静态版

  • 一.前言
    • 1.前期准备
      • a.菜单实现
      • b.联系人结构体的构建
      • c.菜单选项的功能
      • d.#define 的定义
    • 2.功能的实现
      • a.初始化通讯录
      • b.增加联系人
      • c.显示通讯录
      • d.查找联系人
      • e.修改联系人
      • d.删除联系人
    • 3. 总代码
      • test.c
      • contact.c
      • contact.h

一.前言

本文将会用c语言实现一个通讯录的系统,并且存储若干人的信息,每个人的信息包括:姓名,性别,年龄,电话号码,住址。此通讯录系统的功能包括:
1.增加联系人
2.删除对应的联系人
3.查找联系人
4.修改联系人的信息
5.排序此通讯录
6.显示通讯录每个人的信息 。

1.前期准备

建立菜单,十分重要,可以与用户之间建立联系。

菜单中要包含所以功能,以便用户操作。

a.菜单实现

void menu()
{printf("******************************\n");printf("*****   1.add    2.del   *****\n");printf("*****   3.search  4.show *****\n");printf("****    4.modify  6.sort ****\n");printf("****    0.exit           ****\n");printf("*****************************\n");
}

在这里插入图片描述

b.联系人结构体的构建

typedef struct PeoInfo
{char name[MAX_NAME];int age;char tele[MAX_TELE];char sex[MAX_SEX];char addr[MAX_ADDR];
}PeoInfo;typedef struct Contact
{PeoInfo data[MAX];int sz;//记录个数
}Contact;

c.菜单选项的功能

利用枚举enum增加可读性,

再利用 switch函数实现各自功能。

enum Option
{EXIT,//0ADD,//1DEL,//2SEARCH,//3SHOW,//4MODIFY,//5SORT//6
};
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 SHOW:ShowContact(&con);break;case MODIFY:ModifyContact(&con);case SORT:SortContact(&con);case EXIT:printf("退出程序\n");break;default:printf("选择错误\n");break;}} while (input);return 0;
}

d.#define 的定义

便于修改数据,增加可改性

#define MAX 100
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12
#define MAX_ADDR 30

2.功能的实现

a.初始化通讯录

void InitContact(Contact* pc)
{pc->sz= 0;memset(pc->data, 0, sizeof(pc->sz));
} //初始化结构体

b.增加联系人

void AddContact(Contact* pc)
{if (pc->sz == MAX){printf("通讯录已满,无法增加\n");return;}printf("请输入名字:>");scanf("%s", pc->data[pc->sz].name);printf("请输入性别:>");scanf("%s", pc->data[pc->sz].sex);printf("请输入电话:>");scanf("%s", pc->data[pc->sz].tele);printf("请输入地址:>");scanf("%s", pc->data[pc->sz].addr);printf("请输入年龄:>");scanf("%d", &(pc->data[pc->sz].age)); //注意年龄在这是一个int类型,所以传址pc->sz++;printf("添加成功\n");
}

在这里插入图片描述

c.显示通讯录

int cmp_by_name(const void* p1, const void* p2)
{return strcmp(((PeoInfo*)p1)->name, ((PeoInfo*)p2)->name);
}
void SortContact(Contact* pc)
{qsort(pc->data, pc->sz, sizeof(PeoInfo), cmp_by_name);printf("排序成功\n");
}

在这里插入图片描述

d.查找联系人

查找联系人这边我们需要构建一个函数,这个函数需要去根据我们想要寻找的姓名去在通讯录中寻找这个人所对应的位置,加入找到了就可以返回对应位置的下标,否则返回-1。找到之后就和打印通讯录的操作差不多打印出来就好了。

static int FindByName(const Contact* pc, char name[])//通过名字来找
{for (int i = 0;i < pc->sz;i++){if (0 == strcmp(pc->data[i].name, name)){return i;}}return -1;
} //寻找或删除联系人下标
 void SearchContact(Contact* pc)
{char name[MAX_NAME] = { 0 };printf("请输入要查找人的名字:>");scanf("%s", name);int pos = FindByName(pc, name);//pos为要寻找的人的下标if (pos == -1){printf("要查找人不存在\n");return;}printf("%-10s %-4s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");printf("%-10s %-4d %-5s %-12s %-30s\n", pc->data[pos].name, pc->data[pos].age, pc->data[pos].sex,pc->data[pos].tele, pc->data[pos].addr);
}

在这里插入图片描述

e.修改联系人

void ModifyContact(Contact* pc)
{char name[MAX_NAME] = { 0 };printf("请输入要修改人的名字:>");scanf("%s", name);int pos = FindByName(pc, name);if (pos == -1){printf("要修改人不存在\n");return;}printf("请输入名字:>");scanf("%s", pc->data[pc->sz].name);printf("请输入性别:>");scanf("%s", pc->data[pc->sz].sex);printf("请输入电话:>");scanf("%s", pc->data[pc->sz].tele);printf("请输入地址:>");scanf("%s", pc->data[pc->sz].addr);printf("请输入年龄:>");scanf("%d", &(pc->data[pc->sz].age));printf("修改成功\n");
}

d.删除联系人

void DelContact(Contact* pc)
{char name[MAX_NAME] = { 0 };if (pc->sz == 0){printf("通讯录为空,无法删除\n");return;}printf("要删除人的姓名:>");scanf("%s", name);int pos;pos = FindByName(pc, name);if (pos == -1){printf("要删除人不存在\n");return;}int i = 0;for (i = pos;i < pc->sz-1;i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功\n");
}

在这里插入图片描述

3. 总代码

test.c

#include"contact.h"
void menu()
{printf("******************************\n");printf("*****   1.add    2.del   *****\n");printf("*****   3.search  4.show *****\n");printf("****    4.modify  6.sort ****\n");printf("****    0.exit           ****\n");printf("*****************************\n");
}
enum Option
{EXIT,ADD,DEL,SEARCH,SHOW,MODIFY,SORT
};
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 SHOW:ShowContact(&con);break;case MODIFY:ModifyContact(&con);case SORT:SortContact(&con);case EXIT:printf("退出程序\n");break;default:printf("选择错误\n");break;}} while (input);return 0;
}

contact.c

#define _CRT_SECURE_NO_WARNINGS 1#include "contact.h"void InitContact(Contact* pc)
{pc->sz = 0;memset(pc->data, 0, sizeof(pc->data));
}void AddContact(Contact* 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");
}void ShowContact(const Contact* pc)
{int i = 0;//姓名      年龄      性别     电话      地址//zhangsan 20        男      123456    北京////打印标题printf("%-10s %-4s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");//打印数据for (i = 0; i < pc->sz; i++){printf("%-10s %-4d %-5s %-12s %-30s\n",pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].addr);}
}static int FindByName(const Contact* pc, char name[])
{int i = 0;for (i = 0; i < pc->sz; i++){if (0 == strcmp(pc->data[i].name, name)){return i;}}return -1;
}void DelContact(Contact* pc)
{char name[MAX_NAME] = { 0 };if (pc->sz == 0){printf("通讯录为空,无法删除\n");return;}//删除//1. 找到要删除的人 - 位置(下标)printf("输入要删除人的名字:>");scanf("%s", name);int pos = FindByName(pc, name);if (pos == -1){printf("要删除的人不存在\n");return;}int i = 0;//2. 删除 - 删除pos位置上的数据for (i = pos; i < pc->sz - 1; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功\n");
}void SearchContact(const Contact* pc)
{char name[MAX_NAME] = { 0 };printf("请输入要查找人的名字:>");scanf("%s", name);//查找int pos = FindByName(pc, name);if (pos == -1){printf("要查找的人不存在\n");return;}//打印printf("%-10s %-4s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");//打印数据printf("%-10s %-4d %-5s %-12s %-30s\n",pc->data[pos].name,pc->data[pos].age,pc->data[pos].sex,pc->data[pos].tele,pc->data[pos].addr);
}void ModifyContact(Contact* pc)
{char name[MAX_NAME] = { 0 };printf("请输入要修改人的名字:>");scanf("%s", name);int pos = FindByName(pc, name);if (pos == -1){printf("要修改的人不存在\n");return;}//修改printf("请输入名字:>");scanf("%s", pc->data[pos].name);printf("请输入年龄:>");scanf("%d", &(pc->data[pos].age));printf("请输入性别:>");scanf("%s", pc->data[pos].sex);printf("请输入电话:>");scanf("%s", pc->data[pos].tele);printf("请输入地址:>");scanf("%s", pc->data[pos].addr);printf("修改成功\n");
}//按照名字来排序
int cmp_by_name(const void* e1, const void* e2)
{return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}void SortContact(Contact* pc)
{qsort(pc->data, pc->sz, sizeof(PeoInfo), cmp_by_name);printf("排序成功\n");
}

contact.h

#define  _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<string.h>#define MAX 100
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 12
#define MAX_ADDR 30typedef struct PeoInfo
{char name[MAX_NAME];int age;char tele[MAX_TELE];char sex[MAX_SEX];char addr[MAX_ADDR];
}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 SortContact(Contact* pc);//排序通讯录
void ModifyContact(Contact* pc);//修改联系人信息
void SearchContact(Contact* pc);//查找联系人

👊👊👊
感谢阅读!!!
🌸

相关文章:

【C语言】通讯录的实现(静态版)

【C语言】通讯录的实现(静态版一.前言1.前期准备a.菜单实现b.联系人结构体的构建c.菜单选项的功能d.#define 的定义2.功能的实现a.初始化通讯录b.增加联系人c.显示通讯录d.查找联系人e.修改联系人d.删除联系人3. 总代码test.ccontact.ccontact.h一.前言 本文将会用c语言实现一…...

IDEA一键构建Docker镜像

效果 Idea右击Dockerfile文件&#xff0c;直接在服务器构建docker镜像 开整 1、下载docker插件 2、编写Dockerfile文件 # 基础镜像 FROM openjdk:8-jdk-alpine # 工作目录 WORKDIR /opt/apps/gateway/logs/ # 文件拷贝,把target目录下的jar报拷贝到镜像的/APP/目录下 ADD…...

QT的使用3:鼠标事件

鼠标事件0 事件1 需求2 查看控件的事件处理函数3 UI设计4 新建一个类&#xff0c;继承QLabel5 对已有对象进行类型提升6 重写事件处理函数7 项目进一步拓展&#xff08;1&#xff09;获取鼠标按键&#xff08;2&#xff09;鼠标移动&#xff08;3&#xff09;显示多个按键&…...

线程安全之单例模式

文章目录前言一.什么是单例模式二.在java中的单例模式2.1 饿汉式的介绍2.2 懒汉式的介绍三 懒汉式的单例模式,线程不安全的解决方式3.1 造成线程不安全的原因3.2 解决方案3.3 总结前言 这篇文章,我们会介绍一下单例模式,但这里的单例模式,不是我们所说的设计模式,当然听到设计…...

“二分”带来“十分”快感——二分思想的奥秘解析

文章目录无处不在的二分思想二分查找惊人的查找速度二分查找的递归与非递归实现1.循环退出条件2.mid的取值3.low和high的更新最后说一句&#x1f431;‍&#x1f409;作者简介&#xff1a;大家好&#xff0c;我是黑洞晓威&#xff0c;一名大二学生&#xff0c;希望和大家一起进…...

一台服务器最大能支持多少条 TCP 连接?问倒一大片。。。

一台服务器最大能打开的文件数 限制参数 我们知道在Linux中一切皆文件&#xff0c;那么一台服务器最大能打开多少个文件呢&#xff1f;Linux上能打开的最大文件数量受三个参数影响&#xff0c;分别是&#xff1a; fs.file-max &#xff08;系统级别参数&#xff09;&#xf…...

蓝桥杯嵌入式RTC实时时钟

文章目录 前言一、RTC是什么二、cubemx的配置三、函数的使用总结前言 本篇文章将给大家介绍RTC实时时钟。 一、RTC是什么 STM32的实时时钟RTC是一个独立的定时器,RTC时钟内部依靠BCD码计数。RTC实时时钟提高时钟、闹钟、日历功能。RTC功耗较低,可以使用在低功耗设备上。 …...

Centos7 挂载 ISO镜像

切到mnt目录&#xff1a;cd /mnt mkdir iso确保centos镜像在服务上存在,磁盘挂载mount -o loop /home/xx.iso /mnt/iso查看是否挂载成功df -h出现红色的部分表示挂载成功修改源切目录并修改yum源:cd /etc/yum.repos.dllvim Centos-Base.repo修改后yum clean allyum list安装lrz…...

三级数据库备考--数据库应用系统开发方法第一次练习(刷题库知识点记录)

1.数据库的三级模式由外模式、模式、内模式构成。外模式是用户可见的部分数据的存在形式&#xff1b;模式可以等价为全体数据的逻辑结构且用户不可见&#xff0c;是三级模式的中间部分&#xff1b;内模式对应数据库的物理结构和存储方式。当模式改变时&#xff0c;由数据库管理…...

免费空间主机是什么?怎么申请免费空间主机

随着网络的普及&#xff0c;越来越多的人开始使用免费空间。这种新的商业模式也让一些商家得以获利。 1&#xff1a;免费空间的概念 免费空间是指允许您自由使用的网络服务。这意味着它可以被任何人用来创建、编辑和发布网站内容或应用程序&#xff0c;而无需考虑任何付费业务协…...

网络安全文章汇总导航(持续更新)

网络安全文章汇总导航&#xff08;持续更新&#xff09;1.基础篇&#xff08;已完结&#xff09;&#xff1a;2.工具篇&#xff08;持续更新&#xff09;&#xff1a;3.靶场安装&#xff08;持续更新&#xff0c;但不确定&#xff09;&#xff1a;4.权限提升&#xff08;持续更…...

AI-TestOps —— 软件测试工程师的一把利剑

写在前面软件测试的前世今生测试工具开始盛行AI-TestOps 云平台● AI-TestOps 功能模块● AI-TestOps 自动化测试流程写在前面 最近偶然间看到一句话&#xff1a;“软件测试是整个 IT 行业中最差的岗位”。这顿时激起了我对软件测试领域的兴趣&#xff0c;虽然之前未涉及过软件…...

Linux内核进程管理原理详解

前言&#xff1a;Linux内核里大部分都是C语言。建议先看《Linux内核设计与实现(Linux Kernel Development)》,Robert Love&#xff0c;也就是LKD。Linux是一种动态系统&#xff0c;能够适应不断变化的计算需求。Linux计算需求的表现是以进程的通用抽象为中心的。进程可以是短期…...

通过Linux串口实现树莓派与电脑通信

目录 一 串口说明 二 USB—TTL模块 ● usb-ttl模块接口 三 串口通信常用的API 四 修改串口的配置文件 五 串口通信代码验证 ● 发送一个字符/字符串到串口 ● 树莓读取串口数据&#xff08;字符&#xff09; ● 代码拓展&#xff08;双方&#xff09; 一 串口…...

全球变暖 蓝桥杯 178

题目描述你有一张某海域 NxN 像素的照片&#xff0c;"."表示海洋、"#"表示陆地&#xff0c;如下所示&#xff1a;........##.....##........##...####....###........其中"上下左右"四个方向上连在一起的一片陆地组成一座岛屿。例如上图就有 2 座…...

Java现在好找工作吗?

Java到2023年已经28岁了&#xff0c;可能你会怀疑它是否还一如当年一样的强大&#xff0c;在应用层领域独占鳌头。但是基于Java庞大的市场占有率和需求&#xff0c;它依然在保持着更新迭代&#xff0c;依然是最常用的底层开发语言&#xff0c;基于其安全性、开放性、稳定性和跨…...

Flink 第1章 基础介绍和特性

一 Flink概念 1.1 Flink的概念 Flink是一个框架和分布式处理引擎&#xff0c;用于对无界和有解数据流进行状态计算。如下图所示&#xff1a; 1.2 Flink的应用场景 1.3 Flink的目标 1.高吞吐量 2.低延迟 3&#xff0c;结果的准确性和良好的容错性。 1.4 Flink与spark的区别…...

docker 安装 nginx无坑版

一. 拉取镜像 docker pull nginx二. 创建挂载目录 mkdir -p /usr/local/nginx/conf mkdir -p /usr/local/nginx/log mkdir -p /usr/local/nginx/html三. 从nginx容器里复制nginx的配置文件到主机里 创建个容器 docker run --name nginx -p 80:80 -d nginx将容器内的配置文件…...

自己动手做chatGPT:向量的概念和相关操作

chatGPT的横空出世给人工智能注入一针强心剂&#xff0c;它是历史上以最短时间达到一亿用户的应用。chatGPT的能力相当惊人&#xff0c;它可以用相当流利的语言和人对话&#xff0c;同时能够对用户提出的问题给出相当顺畅的答案。它的出现已经给各个行业带来不小冲击&#xff0…...

【洛谷刷题】蓝桥杯专题突破-深度优先搜索-dfs(7)

目录 写在前面&#xff1a; 题目&#xff1a;P1596 [USACO10OCT]Lake Counting S - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题目描述&#xff1a; 输入格式&#xff1a; 输出格式&#xff1a; 输入样例&#xff1a; 输出样例&#xff1a; 解题思路&#xff1a; …...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

网络编程(UDP编程)

思维导图 UDP基础编程&#xff08;单播&#xff09; 1.流程图 服务器&#xff1a;短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

是否存在路径(FIFOBB算法)

题目描述 一个具有 n 个顶点e条边的无向图&#xff0c;该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序&#xff0c;确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数&#xff0c;分别表示n 和 e 的值&#xff08;1…...

C++.OpenGL (14/64)多光源(Multiple Lights)

多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...

C++:多态机制详解

目录 一. 多态的概念 1.静态多态&#xff08;编译时多态&#xff09; 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1&#xff09;.协变 2&#xff09;.析构函数的重写 5.override 和 final关键字 1&#…...

Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合

作者&#xff1a;来自 Elastic Udayasimha Theepireddy (Uday), Brian Bergholm, Marianna Jonsdottir 通过搜索 AI 和云创新推动教育领域的数字化转型。 我们非常高兴地宣布&#xff0c;Elastic 已获得 AWS 教育 ISV 合作伙伴资质。这一重要认证表明&#xff0c;Elastic 作为 …...

GB/T 43887-2024 核级柔性石墨板材检测

核级柔性石墨板材是指以可膨胀石墨为原料、未经改性和增强、用于核工业的核级柔性石墨板材。 GB/T 43887-2024核级柔性石墨板材检测检测指标&#xff1a; 测试项目 测试标准 外观 GB/T 43887 尺寸偏差 GB/T 43887 化学成分 GB/T 43887 密度偏差 GB/T 43887 拉伸强度…...

构建Docker镜像的Dockerfile文件详解

文章目录 前言Dockerfile 案例docker build1. 基本构建2. 指定 Dockerfile 路径3. 设置构建时变量4. 不使用缓存5. 删除中间容器6. 拉取最新基础镜像7. 静默输出完整示例 docker runDockerFile 入门syntax指定构造器FROM基础镜像RUN命令注释COPY复制ENV设置环境变量EXPOSE暴露端…...

Linux【5】-----编译和烧写Linux系统镜像(RK3568)

参考&#xff1a;讯为 1、文件系统 不同的文件系统组成了&#xff1a;debian、ubuntu、buildroot、qt等系统 每个文件系统的uboot和kernel是一样的 2、源码目录介绍 目录 3、正式编译 编译脚本build.sh 帮助内容如下&#xff1a; Available options: uboot …...