手把手教你写通讯录【C语言版】
欢迎光临
各位大帅哥,大美女 如果觉得文章对自己有帮助 可以一键三连支持博主哦
![]()
你们的支持都是我坚持的动力
![]()
前言
建议:我们可以分模块,我这里就分了三个模块,test.c用于专门测试通讯录功能,contact.c和contact.h用于接口的实现和接口的声明
一个简单的通讯录可以用来:
存储1000个人的信息
每个人的基本信息主要是:姓名、电话、年龄、地址、性别……
如果你想要添加别的信息也可以。
通讯录功能:
1、添加联系人
2、查找联系人
3、删除联系人
4、查看所有联系人
5、修改联系人信息
6、按名字排序
相关的函数接口
//初始化通讯录void Initcontact(contact* pa);//增加联系人的信息void Addcontact(contact* pa);//删除指定联系人的信息void Delcontact(contact* pa);//打印通讯录中的信息void Printcontact(contact* pa);//查找指定联系人信息void Searchcontact(const contact* pa);//按字典顺序排序void Sortcontact(contact* pa);//修改指定联系人的信息void Modifycontact(contact* pa);//销毁通讯录void Destroycontact(contact* pa);
目录
1、定义联系人信息和通讯录
- 定义联系人信息
- 定义通讯录内容
2、设计通讯录目录
3、通讯录主函数
4、初始化通讯录
5、打印所有联系人
6、添加联系人
7、删除联系人
8、查找联系人
9、按字母顺序排序通讯录
10、头文件
11、完整代码(附有动态版本和文件版本)
1、定义联系人信息和通讯录
1.1定义联系人信息
这里就要用到结构体了,结构体不熟的要去补补喽。
为了以后方便改数值,我们可以用#define全局变量声明一下。
代码如下:
#define NAME_MAX 20#define SEX_MAX 5#define TELE_MAX 12#define ADDR_MAX 30typedef struct peoinfo{char name[NAME_MAX];char sex[SEX_MAX];int age;char tele[TELE_MAX];char addr[ADDR_MAX];} peoinfo;
1.2定义通讯录的内容
代码如下:
#define MAX 1000typedef struct contact{peoinfo data[MAX];//通讯录容量int sz;//记录通讯录中已经存放的信息个数} contact;
2、设计通讯录目录:
首先我们要设计一个目录,目录的话很简单,可以根据自己喜欢设计,这里就不多说,代码如下:
void menu(){printf("\n");printf(" 1.增加 2.删除 \n");printf(" 3.查找 4.修改 \n");printf(" 5.排序 6.打印 \n");printf(" 0.退出 \n");printf("\n");}
运行结果如下:
3、通讯录主函数
设计完目录后,我们还要把我们的主函数设计出来
代码如下:
void test(){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 MODIFY:Modifycontact(&con);break;case SORT:Sortcontact(&con);break;case PRINT:Printcontact(&con);break;case EXIT:Savecontact(&con);Destroycontact(&con);printf("退出通讯录\n");break;default:printf("选择错误\n");break;}} while (input);}int main(){test();return 0;}
对于这些功能我们可以用枚举来达到这样的效果
代码如下:
//枚举enum Option{EXIT,//退出ADD,//增加DEL,//删除SEARCH,//查找MODIFY,//修改SORT,//排序PRINT//打印};
4、初始化通讯录
最开始我们的通讯录是一个人也没有,所以我们要把通讯录的内容全都初始化为0,否则是随机值,那我们后面在进行下去也是毫无意义的。
代码如下:
void Initcontact(contact* pa){pa->sz = 0;//设置通讯录只有0个元素memset(pa->data, 0, sizeof(pa->data));//初始化数组}
5、打印所有联系人
这个是最简单的,有手就行,不多讲。
代码如下:
void Printcontact(contact* pa){assert(pa);int i = 0;printf("%-10s %-5s %-5s %-12s %-20s\n", "姓名", "年龄", "性别", "电话", "地址");for (i = 0; i sz; i++){printf("%-10s %-5d %-5s %-12s %-20s\n", pa->data[i].name,pa->data[i].age,pa->data[i].sex,pa->data[i].tele,pa->data[i].addr);}}
6、添加联系人
这里我们一定要注意断言哦!!!
这里的判断语句也是需要用动态版本进一步升级的地方。
void Addcontact(contact* pa){assert(pa);if (pa->sz == MAX){printf("通讯录已满,无法添加\n");}//录入信息printf("请输入名字:>");scanf("%s", pa->data[pa->sz].name);printf("请输入年龄:>");scanf("%d", &pa->data[pa->sz].age);printf("请输入性别:>");scanf("%s", pa->data[pa->sz].sex);printf("请输入电话:>");scanf("%s", pa->data[pa->sz].tele);printf("请输入地址:>");scanf("%s", pa->data[pa->sz].addr);pa->sz++;printf("添加成功\n");}
演示结果:
7、 删除联系人
删除联系人分两步,一是先要找到改联系人,二再是删除,还要注意判断一下通讯录是否为空。
代码如下:
//找到了返回下标//找不到返回-1int FindName(const contact* pa, char name[]){ assert(pa); int i = 0; for (i = 0; i sz; i++) { if (0 == strcmp(pa->data[i].name, name)) { return i; } } return -1;}
这里用了一个FindName函数在后面的查找联系人中也用的到。
void Delcontact(contact* pa){assert(pa);if (pa->sz==0){printf("通讯录已空\n");}//1、找到char name[NAME_MAX] = { 0 };printf("请输入要删除的名字:>");scanf("%s", name);int pos = FindName(pa, name);if (pos == -1){printf("要删除的人不存在\n");return;}//2、删除int j = 0;for (j = pos; j sz - 1; j++){pa->data[j] = pa->data[j + 1];}pa->sz--;printf("删除成功\n");}
演示效果:
8、查找联系人
查找联系人我并不需要修改它,所以我们可以用const限定一下。
代码如下:
void Searchcontact(const contact* pa){ char name[NAME_MAX] = { 0 }; printf("请输入要查找的名字:>"); scanf("%s", name); int pos = FindName(pa, name); if (pos == -1) { printf("要查找的人不存在\n"); return; } printf("%-10s %-5s %-5s %-12s %-20s\n", "姓名", "年龄", "性别", "电话", "地址"); printf("%-10s %-5d %-5s %-12s %-20s\n", pa->data[pos].name, pa->data[pos].age, pa->data[pos].sex, pa->data[pos].tele, pa->data[pos].addr);}
演示效果:
9、按字母顺序排序通讯录
这里我用的是qsort函数更简单一点,不过要注意qsort函数的参数不要用错了,当然你们也可以用别的,比如冒泡排序也是可行的。
代码如下:
int Cmpname(const void* e1, const void* e2){return strcmp(((peoinfo*)e1)->name,((peoinfo*)e2)->name);}void Sortcontact(contact* pa){assert(pa);qsort(pa->data, pa->sz, sizeof(pa->data[0]), Cmpname);printf("排序成功\n");}
演示效果:
10、头文件
#include #include #include #include
11、完整代码(附有动态版本和文件版本)
contact.h
#pragma once#include #include #include #include //类型声明#define NAME_MAX 20#define SEX_MAX 5#define TELE_MAX 12#define ADDR_MAX 30#define MAX 1000//通讯录初始状态的容量大小#define DEFAULT_SZ 5//枚举enum Option{EXIT,ADD,DEL,SEARCH,MODIFY,SORT,PRINT};typedef struct peoinfo{char name[NAME_MAX];char sex[SEX_MAX];int age;char tele[TELE_MAX];char addr[ADDR_MAX];} peoinfo;//静态的版本//typedef struct contact//{//peoinfo data[MAX];//通讯录容量//int sz;//记录通讯录中已经存放的信息个数//} contact;//动态的版本typedef struct contact{peoinfo* data;//可以存放1000个人的信息int sz;//记录通讯中已经保存的信息个数int capacity;//记录通讯录当前的最大容量} contact;//函数声明//初始化通讯录void Initcontact(contact* pa);//增加联系人的信息void Addcontact(contact* pa);//删除指定联系人的信息void Delcontact(contact* pa);//打印通讯录中的信息void Printcontact(contact* pa);//查找指定联系人信息void Searchcontact(const contact* pa);//按字典顺序排序void Sortcontact(contact* pa);//修改指定联系人的信息void Modifycontact(contact* pa);//销毁通讯录void Destroycontact(contact* pa);//文件版本void Savecontact(const contact* pa);
contact.c
#define _CRT_SECURE_NO_WARNINGS 1#include "contact.h"//静态的版本//void Initcontact(contact* pa)//{//pa->sz = 0;//memset(pa->data, 0, sizeof(pa->data));//初始化数组//}//动态的版本//void Initcontact(contact* pa)//{//assert(pa);//pa->sz = 0;//pa->capacity = DEFAULT_SZ;//pa->data = (peoinfo*)malloc(pa->capacity * sizeof(peoinfo));//if (pa->data == NULL)//{//perror("Initcontact::malloc");//return;//}//memset(pa->data, 0, pa->capacity * sizeof(peoinfo));//初始化数组//}void checkcapacity(contact* pa)//检查容量{if (pa->sz == pa->capacity){peoinfo* tmp = (peoinfo*)realloc(pa->data, (pa->capacity + 3) * sizeof(peoinfo));if (tmp != NULL){pa->data = tmp;}else{perror("checkcapacity::realloc");return;}pa->capacity += 3;printf("增容成功\n");}}void Loadcontact(contact* pa){//打开文件FILE* pf = fopen("contact.txt", "rb");if (pf == NULL){perror("Loadconatct::fopen");return;}//读文件peoinfo tmp = { 0 };while (fread(&tmp, sizeof(peoinfo), 1, pf)){checkcapacity(pa);pa->data[pa->sz] = tmp;pa->sz++;}//关闭文件fclose(pf);pf = NULL;}//文件版本void Initcontact(contact* pa){assert(pa);pa->sz = 0;pa->capacity = DEFAULT_SZ;pa->data = (peoinfo*)malloc(pa->capacity * sizeof(peoinfo));if (pa->data == NULL){perror("Initcontact::malloc");return;}memset(pa->data, 0, pa->capacity * sizeof(peoinfo));//初始化数组//加载文件信息到通讯录中Loadcontact(pa);}void Addcontact(contact* pa){assert(pa);//静态的版本/*if (pa->sz == MAX){printf("通讯录已满,无法添加\n");}*///录入信息//动态的版本checkcapacity(pa);printf("请输入名字:>");scanf("%s", pa->data[pa->sz].name);printf("请输入年龄:>");scanf("%d", &pa->data[pa->sz].age);printf("请输入性别:>");scanf("%s", pa->data[pa->sz].sex);printf("请输入电话:>");scanf("%s", pa->data[pa->sz].tele);printf("请输入地址:>");scanf("%s", pa->data[pa->sz].addr);pa->sz++;printf("添加成功\n");}//找到了返回下标//找不到返回-1int FindName(const contact* pa, char name[]){assert(pa);int i = 0;for (i = 0; i sz; i++){if (0 == strcmp(pa->data[i].name, name)){return i;}}return -1;}void Delcontact(contact* pa){assert(pa);if (pa->sz==0){printf("通讯录已空\n");}//1、找到char name[NAME_MAX] = { 0 };printf("请输入要删除的名字:>");scanf("%s", name);int pos = FindName(pa, name);if (pos == -1){printf("要删除的人不存在\n");return;}//2、删除int j = 0;for (j = pos; j sz - 1; j++){pa->data[j] = pa->data[j + 1];}pa->sz--;printf("删除成功\n");}void Printcontact(contact* pa){assert(pa);int i = 0;printf("%-10s %-5s %-5s %-12s %-20s\n", "姓名", "年龄", "性别", "电话", "地址");for (i = 0; i sz; i++){printf("%-10s %-5d %-5s %-12s %-20s\n", pa->data[i].name,pa->data[i].age,pa->data[i].sex,pa->data[i].tele,pa->data[i].addr);}}void Searchcontact(const contact* pa){char name[NAME_MAX] = { 0 };printf("请输入要查找的名字:>");scanf("%s", name);int pos = FindName(pa, name);if (pos == -1){printf("要查找的人不存在\n");return;}printf("%-10s %-5s %-5s %-12s %-20s\n", "姓名", "年龄", "性别", "电话", "地址");printf("%-10s %-5d %-5s %-12s %-20s\n", pa->data[pos].name, pa->data[pos].age, pa->data[pos].sex, pa->data[pos].tele, pa->data[pos].addr);}int Cmpname(const void* e1, const void* e2){return strcmp(((peoinfo*)e1)->name,((peoinfo*)e2)->name);}void Sortcontact(contact* pa){assert(pa);qsort(pa->data, pa->sz, sizeof(pa->data[0]), Cmpname);printf("排序成功\n");}void Modifycontact(contact* pa){char name[NAME_MAX] = { 0 };printf("请输入要修改人的名字:>");scanf("%s", name);int pos = FindName(pa, name);if (pos == -1){printf("要修改的人不存在\n");return;}else{printf("请输入修改后的名字:>");scanf("%s", pa->data[pos].name);printf("请输入修改后的年龄:>");scanf("%d", &(pa->data[pos].age));printf("请输入修改后的性别:>");scanf("%s", pa->data[pos].sex);printf("请输入修改后的电话:>");scanf("%s", pa->data[pos].tele);printf("请输入修改后的地址:>");scanf("%s", pa->data[pos].addr);printf("修改成功!!!\n");}printf("%-10s %-5s %-5s %-12s %-20s\n", "姓名", "年龄", "性别", "电话", "地址");printf("%-10s %-5d %-5s %-12s %-20s\n", pa->data[pos].name, pa->data[pos].age, pa->data[pos].sex, pa->data[pos].tele, pa->data[pos].addr);}void Destroycontact(contact* pa){free(pa->data);pa->data = NULL;pa->capacity = 0;pa->sz = 0;printf("销毁成功\n");}//文件版本void Savecontact(const contact* pa){//打开文件FILE* pf = fopen("contact.txt", "wb");if (pf == NULL){perror("Savecontact::fopen");return;}//写文件int i = 0;for (i = 0; i sz; i++){fwrite(pa->data + i, sizeof(peoinfo), 1, pf);}//关闭文件fclose(pf);pf = NULL;}
test.c
#define _CRT_SECURE_NO_WARNINGS 1#include "contact.h"void menu(){printf("\n");printf(" 1.增加 2.删除 \n");printf(" 3.查找 4.修改 \n");printf(" 5.排序 6.打印 \n");printf(" 0.退出 \n");printf("\n");}void test(){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 MODIFY:Modifycontact(&con);break;case SORT:Sortcontact(&con);break;case PRINT:Printcontact(&con);break;case EXIT:Savecontact(&con);Destroycontact(&con);printf("退出通讯录\n");break;default:printf("选择错误\n");break;}} while (input);}int main(){test();return 0;}