c语言通讯录课程设计流程,c语言做通讯录管理系统
终极管理员 知识笔记 125阅读
大家好我是苏貝本篇博客带大家实现通讯录如果你觉得我写的还不错的话可以给我一个赞吗感谢❤️
目录 一. 前言二. 通讯录的实现2.1 写出基本框架2.2 制作menu菜单2.3 创建联系人和通讯录结构体2.4 定义通讯录并初始化2.5 使用枚举常量优化代码2.6 增加联系人信息2.7 删除联系人信息2.8 查找联系人信息2.9 修改联系人信息2.10 打印所有联系人信息2.11 以名字排序所有联系人 三. 模块化代码实现3.1 test.c3.2 contact.h3.3 contact.c3.4 结果演示 四. 存在的问题

一. 前言 二. 通讯录的实现
首先我们建立1个contact.h文件即一个头文件用来声明。建立1个test.c文件用来测试代码。再建立1个contact.c文件用来写实现上述6个功能的代码

下面的代码就是通讯录的基本框架很多程序的基本框架和下面代码相似用do-while循环来决定实现什么功能。变量input作为循环的判断条件如果选择0则退出循环选择1~6之间的数则执行对应的功能选择其它数则提示输入错误再进入循环
int main(){int input 0;do{menu();printf(请选择);scanf(%d, input);switch (input){case 1:break;case 2:break;case 3:break;case 4:break;case 5:break;case 6:break;case 0:printf(退出程序\n);break;default:printf(选择错误请重新输入\n);break;}} while (input);return 0;}
2.2 制作menu菜单 基本框架中有menu菜单那让我们来了解一下如何写menu菜单即一个名为menu的函数。菜单界面就像餐厅里服务员递给你的菜单根据菜单里的内容进行选择。选择1~6实现特定功能选择0退出程序
void menu(){printf(-----------------------------------\n);printf(***********************************\n);printf(****** 1.Add 2.Del ******\n);printf(****** 3.Select 4.Modify ******\n);printf(****** 5.Show 6.Sort ******\n);printf(****** 0.exit ******\n);printf(***********************************\n);printf(-----------------------------------\n);}
2.3 创建联系人和通讯录结构体 因为联系人信息包括姓名、年龄、性别、电话、地址而且它们的类型和所占大小不同所以我们想到构建一个联系人结构体为了书写分别我们将struct PeoInfo重命名为PeoInfo。
typedef struct PeoInfo{char name[20];int age;char gender[5];char tele[12];char addr[30];}PeoInfo;
现在我们将上面字符数组都确定了最大元素个数那如果有一天我们发现有一个人的地址不止30个字节怎么办呢我们接下来的代码里面也可能有addr[30]所以以后修改起来不太方便。因此不妨我们用define定义一些标识符常量之后敲代码时需要用到字符大小就写标识符常量而非一个数字这样可以方便以后修改数组的大小
#define NAME_MAX 20#define GENDER_MAX 5#define TELE_MAX 30#define ADDR_MAX 30typedef struct PeoInfo{char name[NAME_MAX];int age;char gender[GENDER_MAX];char tele[TELE_MAX];char addr[ADDR_MAX];}PeoInfo;
如果我们想存储若干个联系人的信息那我们就要定义一个数组数组有若干个元素元素的类型是PeoInfo很自然的我们用define定义的标识符常量来表示数组的最大元素个数。通讯录除了要有所有联系人信息外也应该可以告诉我们有多少个联系人所以通讯录里要有2个东西一个是若干联系人信息一个是联系人的个数它们的类型不同所以用结构体表示通讯录
#define MAX 1000typedef struct Contact{PeoInfo data[MAX];int sz;}Contact;
2.3 的都是声明语句所以都放在contact.h文件中
2.4 定义通讯录并初始化通讯录的定义简简单单不用多说
Contact con;
我们来想想如何将它初始化。(如果不初始化那么con里面的内容都是随机值)
在test.c文件中调用初始化函数在contact.h中声明初始化函数在contact.c文件中定义函数。结构体传参时最好是传址而非传值且初始化需要改变结构体的内容所以只能传址
InitContact(&con);
初始化就是将变量con的元素sz的值赋值为0并且data数组里面的元素也都是0。sz不用多说将data数组里面的元素全变为0只需应用我们之前介绍过的memset函数了解memset函数
void InitContact(Contact* pc){assert(pc);//断言pc->sz 0;memset(pc->data, 0, sizeof(pc->data));}
2.5 使用枚举常量优化代码 如果不让你看菜单你能知道上面基本框架的switch语句中的case 1~6分别是什么意思吗如果你和我一样不太记得的话那我们可以使用枚举常量来帮助我们识别。枚举常量如果我们自己不去主动赋值的话它们的值会从0开始依次1所以EXIT的值为0ADD的值为1……
enum Option{EXIT,//0ADD,DEL,SELECT,MODIFY,SHOW,SORT};
所以switch语句中的case语句后面的值可以用带提示的枚举常量代替
switch (input){case ADD:break;case DEL:break;case SELECT:break;case MODIFY:break;case SHOW:break;case SORT:break;case EXIT:printf(退出程序\n);break;default:printf(选择错误请重新选择\n);break;}
2.6 增加联系人信息 在test.c文件中调用函数
case ADD:AddContact(&con);break;
在contact.c文件中定义函数。先判断通讯录是否满了若没满则输入联系人信息最好一定要记得sz。注意输入年龄的scanf语句中记得要&
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].gender);printf(请输入电话);scanf(%s, pc->data[pc->sz].tele);printf(请输入地址);scanf(%s, pc->data[pc->sz].addr);pc->sz;printf(增加成功\n);}
2.7 删除联系人信息 在test.c文件中调用函数
case DEL:DelContact(&con);break;
在contact.c文件中定义函数。先判断通讯录是否为空不为空时输入要删除的人的姓名在通过for循环搜索是否有该姓名的联系人因为除了删除联系人信息功能需要搜索以外查找和修改联系人信息也需要通过for循环搜索是否有该姓名的联系人所以不妨将其封装成一个函数。若没有找到这个姓名的联系人返回-1否则返回该姓名的下标。
找到该姓名的联系人以后做删除操作删除操作只需要让下标后面的元素依次向前进一位覆盖掉下标的位置即可。所以循环的结束条件是i < pc->sz - 1不要搞错。覆盖时只需要pc->data[i] pc->data[i 1];因为如果结构体的类型完全相同那就可以整体赋值。最后sz–。可能有人注意到了这个删除操作不能删除最后一个元素是的但没有关系因为我们的sz–了所以之后的遍历中不会再遍历原本的最后一个元素
int FindOfName(char* name, Contact* pc){assert(name && pc);int i 0;for (i 0; i < pc->sz; i){if (0 strcmp(name, (pc->data[i].name)))return i;}return -1;}void DelContact(Contact* pc){assert(pc);char name[NAME_MAX] { 0 };if (pc->sz 0){printf(通讯录为空删除失败\n);return;}printf(请输入要删除的人的名字);scanf(%s, name);int ret FindOfName(name, pc);if (ret -1){printf(找不到要删除的人\n);return;}int i 0;for (i ret; i < pc->sz - 1; i){pc->data[i] pc->data[i 1];}pc->sz--;printf(删除成功\n);}
2.8 查找联系人信息 查找联系人信息同样需要搜索函数FindOfName(name, pc);如果要查找的人存在那么会返回它的下标再通过下标对这个人信息进行打印。为了直观的看出各个信息是属于哪一类的我们可以在打印前打印提示信息注意年龄是%-5s后面打印信息时是%-5d
void SelectContact(Contact* pc){char name[NAME_MAX] { 0 };printf(请输入要查找的人的名字);scanf(%s, name);int ret FindOfName(name, pc);if (ret -1){printf(找不到要查找的人\n);return;}printf(%-20s%-5s%-5s%-30s%-30s\n, 姓名, 年龄, 性别, 电话, 地址);printf(%-20s%-5d%-5s%-30s%-30s\n, pc->data[ret].name, pc->data[ret].age,pc->data[ret].gender, pc->data[ret].tele, pc->data[ret].addr);}
2.9 修改联系人信息 修改联系人信息同样需要搜索函数FindOfName(name, pc);如果要想修改的人存在那么会返回它的下标再通过下标对这个人的全部信息重新输入
void ModifyContact(Contact* pc){assert(pc);char name[NAME_MAX] { 0 };printf(请输入要修改的人的名字);scanf(%s, name);int ret FindOfName(name, pc);if (ret -1){printf(找不到要修改的人\n);return;}printf(请输入名字);scanf(%s, pc->data[ret].name);printf(请输入年龄);scanf(%d, &(pc->data[ret].age));printf(请输入性别);scanf(%s, pc->data[ret].gender);printf(请输入电话);scanf(%s, pc->data[ret].tele);printf(请输入地址);scanf(%s, pc->data[ret].addr);}
2.10 打印所有联系人信息 打印所有联系人信息,无非就是遍历并打印所有元素同样加上提示信息
void ShowContact(Contact* pc){assert(pc);if (pc->sz 0){printf(通讯录为空打印无意义\n);return;}int i 0;printf(%-20s%-5s%-5s%-30s%-30s\n, 姓名, 年龄, 性别, 电话, 地址);for (i 0; i < pc->sz; i){printf(%-20s%-5d%-5s%-30s%-30s\n, pc->data[i].name, pc->data[i].age,pc->data[i].gender, pc->data[i].tele, pc->data[i].addr);}}
2.11 以名字排序所有联系人 使用qsort函数可快速排序了解qsort函数
int cmp(const void* a, const void* b){return strcmp((char*)a, (char*)b);}void SortContact(Contact* pc){assert(pc);qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp);printf(排序成功\n);}
三. 模块化代码实现 3.1 test.c #includecontact.hvoid menu(){printf(-----------------------------------\n);printf(***********************************\n);printf(****** 1.Add 2.Del ******\n);printf(****** 3.Select 4.Modify ******\n);printf(****** 5.Show 6.Init ******\n);printf(****** 7.sort 0.exit ******\n);printf(***********************************\n);printf(-----------------------------------\n);}enum Option{EXIT,ADD,DEL,SELECT,MODIFY,SHOW,INIT,SORT};int main(){Contact con;//初始化通讯录InitContact(&con);int input 0;do{ menu();printf(请选择);scanf(%d, &input);switch (input){case ADD:AddContact(&con);break;case DEL:DelContact(&con);break;case SELECT:SelectContact(&con);break;case MODIFY:ModifyContact(&con);break;case SHOW:ShowContact(&con);break;case INIT:InitContact(&con);break;case SORT:SortContact(&con);break;case EXIT:printf(退出程序\n);break;default:printf(选择错误请重新选择\n);break;}} while (input);return 0;}
3.2 contact.h #pragma once#include<stdio.h>#include<assert.h>#include<string.h>#define NAME_MAX 20#define GENDER_MAX 5#define TELE_MAX 30#define ADDR_MAX 30#define MAX 1000typedef struct PeoInfo{char name[NAME_MAX];int age;char gender[GENDER_MAX];char tele[TELE_MAX];char addr[ADDR_MAX];}PeoInfo;typedef struct Contact{PeoInfo data[MAX];int sz;}Contact;//初始化通讯录void InitContact(Contact* pc);//增加联系人void AddContact(Contact* pc);//删除联系人void DelContact(Contact* pc);//打印通讯录void ShowContact(Contact* pc);//查找联系人void SelectContact(Contact* pc);//修改联系人信息void ModifyContact(Contact* pc);//以名字排序所有联系人void SortContact(Contact* pc);
3.3 contact.c #includecontact.h//初始化通讯录void InitContact(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].gender);printf(请输入电话);scanf(%s, pc->data[pc->sz].tele);printf(请输入地址);scanf(%s, pc->data[pc->sz].addr);pc->sz;printf(增加成功\n);}int FindOfName(char* name, Contact* pc){assert(name && pc);int i 0;for (i 0; i < pc->sz; i){if (0 strcmp(name, (pc->data[i].name)))return i;}return -1;}//删除联系人void DelContact(Contact* pc){assert(pc);char name[NAME_MAX] { 0 };if (pc->sz 0){printf(通讯录为空删除失败\n);return;}printf(请输入要删除的人的名字);scanf(%s, name);int ret FindOfName(name, pc);if (ret -1){printf(找不到要删除的人\n);return;}int i 0;for (i ret; i < pc->sz - 1; i){pc->data[i] pc->data[i 1];}pc->sz--;printf(删除成功\n);}//打印通讯录void ShowContact(Contact* pc){assert(pc);if (pc->sz 0){printf(通讯录为空打印无意义\n);return;}int i 0;printf(%-20s%-5s%-5s%-30s%-30s\n, 姓名, 年龄, 性别, 电话, 地址);for (i 0; i < pc->sz; i){printf(%-20s%-5d%-5s%-30s%-30s\n, pc->data[i].name, pc->data[i].age,pc->data[i].gender, pc->data[i].tele, pc->data[i].addr);}}//查找联系人void SelectContact(Contact* pc){char name[NAME_MAX] { 0 };printf(请输入要查找的人的名字);scanf(%s, name);int ret FindOfName(name, pc);if (ret -1){printf(找不到要查找的人\n);return;}printf(%-20s%-5s%-5s%-30s%-30s\n, 姓名, 年龄, 性别, 电话, 地址);printf(%-20s%-5d%-5s%-30s%-30s\n, pc->data[ret].name, pc->data[ret].age,pc->data[ret].gender, pc->data[ret].tele, pc->data[ret].addr);}//修改联系人信息void ModifyContact(Contact* pc){assert(pc);char name[NAME_MAX] { 0 };printf(请输入要修改的人的名字);scanf(%s, name);int ret FindOfName(name, pc);if (ret -1){printf(找不到要修改的人\n);return;}printf(请输入名字);scanf(%s, pc->data[ret].name);printf(请输入年龄);scanf(%d, &(pc->data[ret].age));printf(请输入性别);scanf(%s, pc->data[ret].gender);printf(请输入电话);scanf(%s, pc->data[ret].tele);printf(请输入地址);scanf(%s, pc->data[ret].addr);}int cmp(const void* a, const void* b){return strcmp((char*)a, (char*)b);}//以名字排序所有联系人void SortContact(Contact* pc){assert(pc);qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp);printf(排序成功\n);}
3.4 结果演示 前面实现的通讯录有什么问题呢?
1.录入的信息等程序结束后还存在吗?不存在了因为数据是存放内存中的只要程序退出掉电都会
丢失怎么解决呢?用文件存储数据库…
2.通讯录的大小是固定的100个元素存放100个人的信息如果信息太多空间小了如果信息太少空间大了。怎么解决?用动态内存管理!
所以期待博主的下一篇优化的通讯录管理系统吧
好了那么本篇博客就到此结束了如果你觉得本篇博客对你有些帮助可以给个大大的赞吗感谢看到这里我们下篇博客见❤️