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

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘

美国西海岸的夏天&#xff0c;再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至&#xff0c;这不仅是开发者的盛宴&#xff0c;更是全球数亿苹果用户翘首以盼的科技春晚。今年&#xff0c;苹果依旧为我们带来了全家桶式的系统更新&#xff0c;包括 iOS 26、iPadOS 26…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

STM32标准库-DMA直接存储器存取

文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA&#xff08;Direct Memory Access&#xff09;直接存储器存取 DMA可以提供外设…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址&#xff1a;pdf 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

大模型多显卡多服务器并行计算方法与实践指南

一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中&#xff0c;部分节点存储的数据量或访问量远高于其他节点&#xff0c;导致这些节点负载过高&#xff0c;影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

AGain DB和倍数增益的关系

我在设置一款索尼CMOS芯片时&#xff0c;Again增益0db变化为6DB&#xff0c;画面的变化只有2倍DN的增益&#xff0c;比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析&#xff1a; 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...

作为测试我们应该关注redis哪些方面

1、功能测试 数据结构操作&#xff1a;验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化&#xff1a;测试aof和aof持久化机制&#xff0c;确保数据在开启后正确恢复。 事务&#xff1a;检查事务的原子性和回滚机制。 发布订阅&#xff1a;确保消息正确传递。 2、性…...