用C实现通讯录(详细讲解+源码)

news/2024/9/24 11:01:35/

 前言

📚作者简介:爱编程的小马,正在学习C/C++,Linux及MySQL..

📚以后会将数据结构收录为一个系列,敬请期待

● 本期内容会给大家带来通讯录的讲解,主要是利用结构体来实现通讯录,该通讯录可以存储几百人甚至是几千人的信息,每个信息包括:姓名,年龄,性别,电话以及地址。准备好了就跟着小马出发吧。


通讯录

 前言

1.通讯录环境及文件配置

2.通讯录的实现

2.1 通讯录的功能

2.2 通讯录的定义

2.3 录入人员信息的函数实现

2.4 定义检查人员是否存在函数

 2.5 删除通讯录中已经存在的信息函数实现

 2.6 查找通讯录成员函数

2.7 修改通讯录成员函数

2.8 显示通讯录

2.9 给通讯录排序

3.通讯录全部源码

3.1 test.c

3.2 contact.h

3.3 contact.c

总结


 

1. 通讯录环境及文件配置

本通讯录是在VS2019的环境下,需要创建三个文件,test.c ,contact.c ,contact.h

test.c //主函数,调用通讯录相关功能

contact.c //函数功能的实现

contact.h //函数头文件的包含及函数的声明

2. 通讯录的实现

2.1 通讯录的功能

2.2 通讯录的定义

首先需要一个菜单,可以提供给玩家选择:

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

 通讯录的定义:

1、封装一个结构体信息用来存储人员信息

2、再需要一个结构体数组来管理这个人员信息(暂时能存储100个人)


#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 20
#define ADDR_MAX 30
#define ADD_ONCE 2
#define MAX 100
typedef struct peoinfo
{char name[NAME_MAX];int age;char sex[SEX_MAX];char tele[TELE_MAX];char addr[ADDR_MAX];
}peoinfo;
typedef struct contact
{peoinfo data [MAX];int sz;
}contact;

2.3 录入人员信息的函数实现

1、判断:如果人员信息录入满了就不再录入了

2、挨个录入姓名,年龄,性别,电话以及住址,录入完成后打印增加成功,然后记录人员信息的sz往后走一步(sz++)

void AddContact(contact* pc)
{assert(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");
}

2.4 定义检查人员是否存在函数

为什么要定义这个函数呢?因为两点原因:1、后面的删除,查找,修改人员信息是不是都要先确定这个人是否存在我们再进行下一步操作。2、在前面定义,后面直接引用即可,不用反复定义


int FindName(contact* pc,char name[])
{int i = 0;for (i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0)return i;}return -1;
}

 2.5 删除通讯录中已经存在的信息函数实现

1、判断:如果通讯录为空,就不要删除了,直接返回

2、如果不为空,我们就调用检查人员是否存在这个函数,如果存在,则继续,如果不存在,就返回

3、如果有这个人,那应该从这个人的地址往后,依次向前覆盖,最后总数sz-1是不是就完成了删除

void DelContact(contact* pc)
{char name[NAME_MAX];printf("请输入要删除人的名字:>");scanf("%s", name);if (pc->sz == 0){printf("通讯录为空,无法删除\n");return;}int ret = FindName(pc, name);if (ret == -1){printf("查无此人,无法删除请重试\n");return;}int i = 0;for (i = ret; i < ret - 1; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功\n");
}

 2.6 查找通讯录成员函数

1、判断:如果通讯录为空,不要查找了直接返回

2、调用检查人员存在函数,如果没有就直接返回,如果存在就直接打印人员信息

void SearchContact(contact* pc)
{char name[NAME_MAX];int i = 0;printf("请输入被查找人的名字:>");scanf("%s", name);int ret = FindName(pc, name);if (ret == -1){printf("查无此人\n");}else{printf("%-20s%-5s%-5s%-12s%-20s\n", "姓名", "年龄", "性别", "电话", "地址");printf("%-20s%-5d%-5s%-12s%-20s\n", pc->data[ret].name,pc->data[ret].age,pc->data[ret].sex,pc->data[ret].tele,pc->data[ret].addr);}
}

2.7 修改通讯录成员函数

1、判断:如果通讯录为空就不要修改了,直接返回

2、调用检查人员存在函数,如果没有就直接返回,如果存在就直接修改人员信息

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

2.8 显示通讯录

void ShowContact(contact* pc)
{assert(pc);if (pc->sz == 0)printf("通讯录为空,无需打印\n");else{int i = 0;for (i = 0; i < pc->sz; i++){printf("%-20s%-5s%-5s%-12s%-20s\n", "姓名", "年龄", "性别", "电话", "地址");printf("%-20s%-5d%-5s%-12s%-20s\n", pc->data[i].name,pc->data[i].age,pc->data[i].sex,pc->data[i].tele,pc->data[i].addr);}}
}

2.9 给通讯录排序

1、首先需要确定按什么排序

2、实现的思想是使用qsort函数

void menun()
{printf("******************************\n");printf("**** 1.按名字    2.按年龄 ****\n");printf("**** 3.按性别    4.按电话 ****\n");printf("**** 5.按地址             ****\n");printf("******************************\n");
}
int NAME(const void* p1, const void* p2)
{return strcmp(((peoinfo*)p1)->name, ((peoinfo*)p2)->name);
}int AGE(const void* p1, const void* p2)
{return (((peoinfo*)p1)->age- ((peoinfo*)p2)->age);
}
int SEX(const void* p1, const void* p2)
{return strcmp(((peoinfo*)p1)->sex, ((peoinfo*)p2)->sex);
}
int TELE(const void* p1, const void* p2)
{return strcmp(((peoinfo*)p1)->tele, ((peoinfo*)p2)->tele);
}
int ADDR(const void* p1, const void* p2)
{return strcmp(((peoinfo*)p1)->addr, ((peoinfo*)p2)->addr);
}
void SortContact(contact* pc)
{menun();int input = 0;printf("请输入排序的方式:>");scanf("%d", &input);int (*cmp[6])(const void* p1, const void* p2) = { NULL,NAME,AGE,SEX,TELE,ADDR};switch (input){case 1:qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);break;case 2:qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);break;case 3:qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);break;case 4:qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);break;case 5:qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);break;default:printf("输入非法\n");}printf("排序成功\n");
}

3. 通讯录全部源码

3.1 test.c

#define  _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"
void menu()
{printf("******************************\n");printf("**** 1.add       2.del    ****\n");printf("**** 3.search    4.modify ****\n");printf("**** 5.show      6.sort   ****\n");printf("**** 0.exit               ****\n");printf("******************************\n");}
enum Option
{EXIT,ADD,DEL,SEARCH,MODIFY,SHOW,SORT
};
int main()
{int input = 0;contact con;Init(&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 MODIFY:ModifyContact(&con);break;case SHOW:ShowContact(&con);break;case SORT:SortContact(&con);break;case EXIT:{printf("退出程序\n");break;}default:printf("非法输入,请重新输入\n");}} while (input);return 0;
}

3.2 contact.h

#pragma once
#include<stdio.h>
#include<assert.h>
#include<string.h>
#include<stdlib.h>#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 20
#define ADDR_MAX 30
#define ADD_ONCE 2
#define MAX 100
typedef struct peoinfo
{char name[NAME_MAX];int age;char sex[SEX_MAX];char tele[TELE_MAX];char addr[ADDR_MAX];
}peoinfo;
typedef struct contact
{peoinfo data [MAX];int sz;
}contact;void Init(contact * pc);
void  AddContact(contact* pc);void ShowContact(contact*pc);void DelContact(contact* pc);void SearchContact(contact *pc);void ModifyContact(contact* pc);void SortContact(contact* pc);void free_contact(contact *pc);

3.3 contact.c

#define  _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"void Init(contact* pc)
{//静态版assert(pc);pc->sz = 0;memset(pc->data, 0, sizeof(pc->data));
}
void AddContact(contact* pc)
{assert(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(contact* pc)
{assert(pc);if (pc->sz == 0)printf("通讯录为空,无需打印\n");else{int i = 0;for (i = 0; i < pc->sz; i++){printf("%-20s%-5s%-5s%-12s%-20s\n", "姓名", "年龄", "性别", "电话", "地址");printf("%-20s%-5d%-5s%-12s%-20s\n", pc->data[i].name,pc->data[i].age,pc->data[i].sex,pc->data[i].tele,pc->data[i].addr);}}
}//从后往前覆盖就好了,总数删除完毕之后再减一个int FindName(contact* pc,char name[])
{int i = 0;for (i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0)return i;}return -1;
}
void DelContact(contact* pc)
{char name[NAME_MAX];printf("请输入要删除人的名字:>");scanf("%s", name);if (pc->sz == 0){printf("通讯录为空,无法删除\n");return;}int ret = FindName(pc, name);if (ret == -1){printf("查无此人,无法删除请重试\n");return;}int i = 0;for (i = ret; i < ret - 1; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功\n");
}void SearchContact(contact* pc)
{char name[NAME_MAX];int i = 0;printf("请输入被查找人的名字:>");scanf("%s", name);int ret = FindName(pc, name);if (ret == -1){printf("查无此人\n");}else{printf("%-20s%-5s%-5s%-12s%-20s\n", "姓名", "年龄", "性别", "电话", "地址");printf("%-20s%-5d%-5s%-12s%-20s\n", pc->data[ret].name,pc->data[ret].age,pc->data[ret].sex,pc->data[ret].tele,pc->data[ret].addr);}
}void ModifyContact(contact* pc)
{char name[NAME_MAX];int i = 0;printf("请输入要修改人的名字:>");scanf("%s", name);int ret = FindName(pc, name);if (ret == -1)printf("要修改的人不存在\n");else{printf("请输入名字:>");scanf("%s", pc->data[ret].name);printf("请输入年龄:>");scanf("%d", &pc->data[ret].age);printf("请输入性别:>");scanf("%s", pc->data[ret].sex);printf("请输入电话:>");scanf("%s", pc->data[ret].tele);printf("请输入地址:>");scanf("%s", pc->data[ret].addr);printf("修改成功\n");}}void menun()
{printf("******************************\n");printf("**** 1.按名字    2.按年龄 ****\n");printf("**** 3.按性别    4.按电话 ****\n");printf("**** 5.按地址             ****\n");printf("******************************\n");
}
int NAME(const void* p1, const void* p2)
{return strcmp(((peoinfo*)p1)->name, ((peoinfo*)p2)->name);
}int AGE(const void* p1, const void* p2)
{return (((peoinfo*)p1)->age- ((peoinfo*)p2)->age);
}
int SEX(const void* p1, const void* p2)
{return strcmp(((peoinfo*)p1)->sex, ((peoinfo*)p2)->sex);
}
int TELE(const void* p1, const void* p2)
{return strcmp(((peoinfo*)p1)->tele, ((peoinfo*)p2)->tele);
}
int ADDR(const void* p1, const void* p2)
{return strcmp(((peoinfo*)p1)->addr, ((peoinfo*)p2)->addr);
}
void SortContact(contact* pc)
{menun();int input = 0;printf("请输入排序的方式:>");scanf("%d", &input);int (*cmp[6])(const void* p1, const void* p2) = { NULL,NAME,AGE,SEX,TELE,ADDR};switch (input){case 1:qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);break;case 2:qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);break;case 3:qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);break;case 4:qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);break;case 5:qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);break;default:printf("输入非法\n");}printf("排序成功\n");
}

总结

上文就是通讯录的详细讲解和全部源码,下一节会给大家更新动态内存存储相关的知识。

如果这份博客对大家有帮助,希望各位给小马一个大大的点赞鼓励一下,如果喜欢,请收藏一下,谢谢大家!!!
制作不易,如果大家有什么疑问或给小马的意见,欢迎评论区留言。


http://www.ppmy.cn/news/1440958.html

相关文章

ITMS-90426: Invalid Swift Support

原文 Please correct the following issues and upload a new binary to App Store Connect. ITMS-90426: Invalid Swift Support - The SwiftSupport folder is missing. Rebuild your app using the current public (GM) version of Xcode and resubmit it. 解决方式 ITMS-…

FIR补偿滤波器——matlab的FDA实现

输入采样频率&#xff1a;192KHz 抽取倍数&#xff1a;2 通带截至频率&#xff1a;20KHz 通带衰减&#xff1a;0.1dB 阻带衰减&#xff1a;120dB 在更多选项那里&#xff0c;设置c为0.5&#xff0c;代表抽取倍数为1/c&#xff0c;p设置为4&#xff0c;代表级联阶数。FIR补偿…

机器学习:深入解析SVM的核心概念(问题与解答篇)【一、间隔与支持向量】

直接阅读原始论文可能有点难和复杂&#xff0c;所以导师直接推荐我阅读周志华的《西瓜书》&#xff01;&#xff01;然后仔细阅读其中的第六章&#xff1a;支持向量机 间隔与支持向量 问题一&#xff1a;什么叫法向量&#xff1f;为什么是叫法向量 在这个线性方程中&#xff…

Int4:Lucene 中的更多标量量化

作者&#xff1a;来自 Elastic Benjamin Trent, Thomas Veasey 在 Lucene 中引入 Int4 量化 在之前的博客中&#xff0c;我们全面介绍了 Lucene 中标量量化的实现。 我们还探索了两种具体的量化优化。 现在我们遇到了一个问题&#xff1a;int4 量化在 Lucene 中是如何工作的以…

阳光电源社招前程无忧智鼎题库及远程包过助攻需要重点考察什么?

阳光电源社招前程无忧智鼎题库及远程包过助攻需要重点考察什么&#xff1f; 结合长期服务大型国有企业校招工作的经验&#xff0c;我们总结出阳光电源社招笔试的典型模式&#xff1a;行政职业能力测试企业应知应会测试心理测评&#xff0c;综合考察候选人的政治素养、文化素养…

PaddleSeg数据集的准备

PaddleSeg数据集格式 1、数据集及图片名称和目录无中文或奇怪字符 2、所有图片一个文件夹&#xff0c;所有标注一个文件夹&#xff0c;利用txt文件索引&#xff08;当然有需要也可以使用不同文件夹&#xff0c;自己处理这个txt索引文件即可&#xff09; 3、图片jpg格式&#x…

Swift中TableView的编辑模式

Swift中TableView的编辑模式可以通过UITableView的属性isEditing来控制。 要将TableView设置为编辑模式&#xff0c;可以使用以下代码&#xff1a; tableView.isEditing true要退出编辑模式&#xff0c;可以使用以下代码&#xff1a; tableView.isEditing false当TableVie…

[ESP32]:TFLite Micro推理CIFAR10模型

[ESP32]&#xff1a;TFLite Micro推理CIFAR10模型 模型训练 数据集处理 from keras.datasets import cifar10 from keras.preprocessing.image import ImageDataGenerator from keras.models import Sequential, load_model, Model from keras.layers import Input, Dense, …