目录
前言
在我们的日藏生活中,经常会通过手机来互相联系交流,而我们常常会把常联系的电话号码添加进我们的通讯录里面。它是一种利用互联网或实现通讯录信息同步更新和备份的应用,服务。你可以在个人电脑、移动电话等任何联网设备上录入你的联系人的手机,通信地址等通讯录信息,或对以前的信息进行分组、管理和更新,在你的许可下,该联系人可以看到他所在组内的其他联系人信息,从而实现通讯录共享,如果该联系人更新自己的联系信息,你的通讯录会自动更新,实现同步通讯录,并留下旧版本的通讯录信息。但这里的原理和代码是怎么样的我们就不得而知了。今天我们就通过C来编写通讯录的后端代码,我们将分为三个版本来实现,由易到难,干货满满,大家放心食用。
基本要求
通讯录可以存储多个人的信息,信息需要包括:姓名 年龄 性别 地址 电话
功能:
添加新增联系人
删除不需要的联系人
查找联系人
修改联系人信息
查看所有联系人信息
可以对联系人进行排序
通讯录实现思想
通讯录的构成
为了让代码不会太过冗余,这里将用三个文件test.c contact.c contact.h 来存放代码. test.c用于来测试我们的代码, contact.c来实现通讯录需要的函数代码,contact.h用来存放函数的声明和头文件包含。
设计思路
添加一个菜单提示用户如何使用
让通讯录可以多次使用
设置一个合理的变量为通讯录,对通讯录进行初始化
实现功能所需要的函数
具体代码
静态版本
contact.h
#include <stdio.h> #include <assert.h> #include <string.h> #include <stdlib.h> #define MAX 1000 #define MAX_NAME 10 #define MAX_SEX 4 #define MAX_ADDRESS 10 #define MAX_TELE 11 enum OPION { eit, add, del, modfiy, search, show, sort }; typedef struct ProInfo { char name[MAX_NAME]; char sex[MAX_SEX]; char address[MAX_ADDRESS]; char tele[MAX_TELE]; int age; }ProInfo; typedef struct contact { ProInfo data[MAX]; int sz; }contact; //初始化 void Initcontact(contact* pc); //添加 void addconcact(contact* pc); //显示 void showcontact(contact* pc); //删除 void delcontact(contact* pc); //修改 void modfiycontact(contact* pc); //查找 void searchcontact(contact* pc); //排序 void sortcontact(contact* pc);
contact.c
#include "contact.h" //初始化 void Initcontact(contact* pc) { memset(pc->data, 0, sizeof(pc->data)); pc->sz = 0; } //增加 void addconcact(contact* pc) { if (pc->sz == MAX) { printf("通迅录已满,无法再添加\n"); return; } printf("姓名:\n"); scanf("%s", pc->data[pc->sz].name); printf("年龄:\n"); scanf("%d", &(pc->data[pc->sz].age)); printf("性别:\n"); scanf("%s", pc->data[pc->sz].sex); printf("电话:\n"); scanf("%s", pc->data[pc->sz].tele); printf("住址:\n"); scanf("%s", pc->data[pc->sz].address); pc->sz++; printf("添加联系人成功\n"); } //显示 void showcontact(contact* pc) { printf("%-8s\t%-6s\t%6s\t%-15s\t%-10s\n", "名字", "年龄", "性别", "电话", "住址"); int i = 0; for (i = 0; i < pc->sz; i++) { printf("%-8s\t%-6d\t%-6s\t%-15s\t%-10s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].address); } } //查找 int Findcontact(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) { if (pc->sz == 0) { printf("通讯录为空,无法删除\n"); return; } char name[MAX_NAME] = {0}; printf("输入要查找的对象:\n"); scanf("%s", name); int del = Findcontact(pc, name); if (del == -1) { printf("查找的人不存在\n"); return; } int i = 0; for (i = del; del < pc->sz-1; i++) { pc->data[i] = pc->data[i + 1]; } pc->sz--; printf("删除成功\n"); } //修改 void modfiycontact(contact* pc) { char name[MAX_NAME] = { 0 }; printf("请输入要修改的对象:\n"); scanf("%s", name); int flag = Findcontact(pc, name); if (flag == -1) { printf("修改对象不存在,修改失败\n"); return; } printf("姓名:\n"); scanf("%s", pc->data[flag].name); printf("年龄:\n"); scanf("%d", &(pc->data[flag].age)); printf("性别:\n"); scanf("%s", pc->data[flag].sex); printf("电话:\n"); scanf("%s", pc->data[flag].tele); printf("住址:\n"); scanf("%s", pc->data[flag].address); } //查找 void searchcontact(contact* pc) { char name[MAX_NAME] = { 0 }; printf("请输入查找的对象:\n"); scanf("%s", name); int flag = Findcontact(pc, name); if (flag == -1) { printf("查找失败\n"); return; } printf("%-8s\t%-6d\t%-6s\t%-15s\t%-10s\n", pc->data[flag].name, pc->data[flag].age, pc->data[flag].sex, pc->data[flag].tele, pc->data[flag].address); } //名字排序 int comper_name(const void* e1, const void* e2) { return strcmp(((ProInfo*)e1)->name, ((ProInfo*)e2)->name); } //年龄排序 int comper_age(const void* e1, const void* e2) { return ((ProInfo*)e1)->age - ((ProInfo*)e2)->age; } //性别排序 int comper_sex(const void* e1, const void* e2) { return strcmp(((ProInfo*)e1)->sex, ((ProInfo*)e2)->sex); } //排序 void sortcontact(contact* pc) { printf("***************************\n"); printf("1. 名字排序 2. 年龄排序\n"); printf("3. 性别排序 \n"); printf("***************************\n"); printf("请选择排序方法:"); int input = 0; scanf("%d", &input); switch (input) { case 1: qsort(pc->data, pc->sz, sizeof(ProInfo), comper_name); showcontact(pc); printf("排序成功\n"); break; case 2: qsort(pc->data, pc->sz, sizeof(ProInfo), comper_age); showcontact(pc); printf("排序完成\n"); break; case 3: qsort(pc->data, pc->sz, sizeof(ProInfo), comper_sex); showcontact(pc); printf("排序完成\n"); break; default: printf("选择错误\n"); break; } }
test.c
#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() { menu(); int input = 0; contact con; //初始化通讯录 Initcontact(&con); do { printf("请输入:\n"); scanf("%d", &input); switch (input) { case add: //添加 addconcact(&con); break; case del: //删除 delcontact(&con); break; case modfiy: //修改 modfiycontact(&con); break; case search: //查找 searchcontact(&con); break; case show: //显示 showcontact(&con); break; case sort: //排序 sortcontact(&con); break; case eit: printf("退出成功\n"); break; default: printf("输入错误,请重新输入\n"); break; } } while (input); } int main() { test(); return 0; }
动态版本
上面的版本我们发现通讯录是固定的,添加满后不能继续添加,我们需要设计一个可以增容的代码。
malloc_contact.h
#include <stdio.h> #include <assert.h> #include <string.h> #include <stdlib.h> #include <stdlib.h> #define MAX 2 #define MAX_NAME 10 #define MAX_SEX 4 #define MAX_ADDRESS 10 #define MAX_TELE 11 #define MAX_SZ 2 enum OPION { eit, add, del, modfiy, search, show, sort }; typedef struct ProInfo { char name[MAX_NAME]; char sex[MAX_SEX]; char address[MAX_ADDRESS]; char tele[MAX_TELE]; int age; }ProInfo; typedef struct contact { ProInfo* data; int sz; int max; }contact; //初始化 void Initcontact(contact* pc); //添加 void addconcact(contact* pc); //显示 void showcontact(contact* pc); //删除 void delcontact(contact* pc); //修改 void modfiycontact(contact* pc); //查找 void searchcontact(contact* pc); //排序 void sortcontact(contact* pc); //释放空间 void Destroycontact(contact* pc);
malloc_contact.c
#include "contact.h" //初始化 void Initcontact(contact* pc) { pc->data = (ProInfo*)malloc(MAX_SZ * sizeof(ProInfo)); pc->sz = 0; pc->max = MAX_SZ; } //增加容量 int CheckCapacity(contact* pc) { ProInfo* pf = (ProInfo*)realloc(pc->data, (pc->max + MAX_SZ) * sizeof(ProInfo)); if (pf == NULL) { return 0; } pc->data = pf; pc->max += MAX_SZ; printf("增容成功\n"); return 1; } //增加 void addconcact(contact* pc) { if (pc->sz == pc->max) { if (0 == CheckCapacity(pc)) { printf("通讯录已满,增容失败\n"); return 1; } } printf("姓名:\n"); scanf("%s", pc->data[pc->sz].name); printf("年龄:\n"); scanf("%d", &(pc->data[pc->sz].age)); printf("性别:\n"); scanf("%s", pc->data[pc->sz].sex); printf("电话:\n"); scanf("%s", pc->data[pc->sz].tele); printf("住址:\n"); scanf("%s", pc->data[pc->sz].address); pc->sz++; printf("添加联系人成功\n"); } //显示 void showcontact(contact* pc) { printf("%-8s\t%-6s\t%6s\t%-15s\t%-10s\n", "名字", "年龄", "性别", "电话", "住址"); int i = 0; for (i = 0; i < pc->sz; i++) { printf("%-8s\t%-6d\t%-6s\t%-15s\t%-10s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].address); } } //查找 int Findcontact(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) { if (pc->sz == 0) { printf("通讯录为空,无法删除\n"); return; } char name[MAX_NAME] = {0}; printf("输入要查找的对象:\n"); scanf("%s", name); int del = Findcontact(pc, name); if (del == -1) { printf("查找的人不存在\n"); return; } int i = 0; for (i = del; del < pc->sz-1; i++) { pc->data[i] = pc->data[i + 1]; } pc->sz--; printf("删除成功\n"); } //修改 void modfiycontact(contact* pc) { char name[MAX_NAME] = { 0 }; printf("请输入要修改的对象:\n"); scanf("%s", name); int flag = Findcontact(pc, name); if (flag == -1) { printf("修改对象不存在,修改失败\n"); return; } printf("姓名:\n"); scanf("%s", pc->data[flag].name); printf("年龄:\n"); scanf("%d", &(pc->data[flag].age)); printf("性别:\n"); scanf("%s", pc->data[flag].sex); printf("电话:\n"); scanf("%s", pc->data[flag].tele); printf("住址:\n"); scanf("%s", pc->data[flag].address); } //查找 void searchcontact(contact* pc) { char name[MAX_NAME] = { 0 }; printf("请输入查找的对象:\n"); scanf("%s", name); int flag = Findcontact(pc, name); if (flag == -1) { printf("查找失败\n"); return; } printf("%-8s\t%-6d\t%-6s\t%-15s\t%-10s\n", pc->data[flag].name, pc->data[flag].age, pc->data[flag].sex, pc->data[flag].tele, pc->data[flag].address); } //名字排序 int comper_name(const void* e1, const void* e2) { return strcmp(((ProInfo*)e1)->name, ((ProInfo*)e2)->name); } //年龄排序 int comper_age(const void* e1, const void* e2) { return ((ProInfo*)e1)->age - ((ProInfo*)e2)->age; } //性别排序 int comper_sex(const void* e1, const void* e2) { return strcmp(((ProInfo*)e1)->sex, ((ProInfo*)e2)->sex); } //排序 void sortcontact(contact* pc) { printf("***************************\n"); printf("1. 名字排序 2. 年龄排序\n"); printf("3. 性别排序 \n"); printf("***************************\n"); printf("请选择排序方法:"); int input = 0; scanf("%d", &input); switch (input) { case 1: qsort(pc->data, pc->sz, sizeof(ProInfo), comper_name); showcontact(pc); printf("排序成功\n"); break; case 2: qsort(pc->data, pc->sz, sizeof(ProInfo), comper_age); showcontact(pc); printf("排序完成\n"); break; case 3: qsort(pc->data, pc->sz, sizeof(ProInfo), comper_sex); showcontact(pc); printf("排序完成\n"); break; default: printf("选择错误\n"); break; } } //释放空间 void Destroycontact(contact* pc) { free(pc->data); pc->data = NULL; }
malloc_test.c
#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() { menu(); int input = 0; contact con; //初始化通讯录 Initcontact(&con); do { printf("请输入:\n"); scanf("%d", &input); switch (input) { case add: //添加 addconcact(&con); break; case del: //删除 delcontact(&con); break; case modfiy: //修改 modfiycontact(&con); break; case search: //查找 searchcontact(&con); break; case show: //显示 showcontact(&con); break; case sort: //排序 sortcontact(&con); break; case eit: Destroycontact(&con); printf("退出成功\n"); break; default: printf("输入错误,请重新输入\n"); break; } } while (input); } int main() { test(); return 0; }
文件版本
上面的代码虽然可以实现增容,但是可以发现一旦程序退出后,下次代码再运行起来上一次的数据就丢失了。我们需要一个可以一直保存数据的代码。
FILE_contact.h
#include <stdio.h> #include <assert.h> #include <string.h> #include <stdlib.h> #include <stdlib.h> #define MAX 2 #define MAX_NAME 10 #define MAX_SEX 4 #define MAX_ADDRESS 10 #define MAX_TELE 11 #define MAX_SZ 2 enum OPION { eit, add, del, modfiy, search, show, sort }; typedef struct ProInfo { char name[MAX_NAME]; char sex[MAX_SEX]; char address[MAX_ADDRESS]; char tele[MAX_TELE]; int age; }ProInfo; typedef struct contact { ProInfo* data; int sz; int max; }contact; //初始化 void Initcontact(contact* pc); //添加 void addconcact(contact* pc); //显示 void showcontact(contact* pc); //删除 void delcontact(contact* pc); //修改 void modfiycontact(contact* pc); //查找 void searchcontact(contact* pc); //排序 void sortcontact(contact* pc); //释放空间 void Destroycontact(contact* pc); //保存 void Savecontact(contact* pc);
FILE_contact.c
#include "FILE_contact.h" //初始化 int CheckCapacity(contact* pc); void Loadcontact(contact* pc) { FILE* pf = fopen("contact.txt", "rb"); if (pf == NULL) { perror("Loadcontact"); return ; } ProInfo tmp = { 0 }; while (fread(&tmp, sizeof(ProInfo), 1, pf)) { if (0 == CheckCapacity(pc)) return; pc->data[pc->sz] = tmp; pc->sz++; } fclose(pf); pf = NULL; } void Initcontact(contact* pc) { pc->data = (ProInfo*)malloc(MAX_SZ * sizeof(ProInfo)); pc->sz = 0; pc->max = MAX_SZ; Loadcontact(pc); } //增加容量 int CheckCapacity(contact* pc) { if (pc->sz == pc->max) { ProInfo* pf = (ProInfo*)realloc(pc->data, (pc->max + MAX_SZ) * sizeof(ProInfo)); if (pf == NULL) { return 0; } pc->data = pf; pc->max += MAX_SZ; printf("增容成功\n"); return 1; } return 1; } //增加 void addconcact(contact* pc) { if (0 == CheckCapacity(pc)) { printf("通讯录已满,增容失败\n"); return 1; } printf("姓名:\n"); scanf("%s", pc->data[pc->sz].name); printf("年龄:\n"); scanf("%d", &(pc->data[pc->sz].age)); printf("性别:\n"); scanf("%s", pc->data[pc->sz].sex); printf("电话:\n"); scanf("%s", pc->data[pc->sz].tele); printf("住址:\n"); scanf("%s", pc->data[pc->sz].address); pc->sz++; printf("添加联系人成功\n"); } //显示 void showcontact(contact* pc) { printf("%-8s\t%-6s\t%6s\t%-15s\t%-10s\n", "名字", "年龄", "性别", "电话", "住址"); int i = 0; for (i = 0; i < pc->sz; i++) { printf("%-8s\t%-6d\t%-6s\t%-15s\t%-10s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].address); } } //查找 int Findcontact(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) { if (pc->sz == 0) { printf("通讯录为空,无法删除\n"); return; } char name[MAX_NAME] = { 0 }; printf("输入要查找的对象:\n"); scanf("%s", name); int del = Findcontact(pc, name); if (del == -1) { printf("查找的人不存在\n"); return; } int i = 0; for (i = del; del < pc->sz - 1; i++) { pc->data[i] = pc->data[i + 1]; } pc->sz--; printf("删除成功\n"); } //修改 void modfiycontact(contact* pc) { char name[MAX_NAME] = { 0 }; printf("请输入要修改的对象:\n"); scanf("%s", name); int flag = Findcontact(pc, name); if (flag == -1) { printf("修改对象不存在,修改失败\n"); return; } printf("姓名:\n"); scanf("%s", pc->data[flag].name); printf("年龄:\n"); scanf("%d", &(pc->data[flag].age)); printf("性别:\n"); scanf("%s", pc->data[flag].sex); printf("电话:\n"); scanf("%s", pc->data[flag].tele); printf("住址:\n"); scanf("%s", pc->data[flag].address); } //查找 void searchcontact(contact* pc) { char name[MAX_NAME] = { 0 }; printf("请输入查找的对象:\n"); scanf("%s", name); int flag = Findcontact(pc, name); if (flag == -1) { printf("查找失败\n"); return; } printf("%-8s\t%-6d\t%-6s\t%-15s\t%-10s\n", pc->data[flag].name, pc->data[flag].age, pc->data[flag].sex, pc->data[flag].tele, pc->data[flag].address); } //名字排序 int comper_name(const void* e1, const void* e2) { return strcmp(((ProInfo*)e1)->name, ((ProInfo*)e2)->name); } //年龄排序 int comper_age(const void* e1, const void* e2) { return ((ProInfo*)e1)->age - ((ProInfo*)e2)->age; } //性别排序 int comper_sex(const void* e1, const void* e2) { return strcmp(((ProInfo*)e1)->sex, ((ProInfo*)e2)->sex); } //排序 void sortcontact(contact* pc) { printf("***************************\n"); printf("1. 名字排序 2. 年龄排序\n"); printf("3. 性别排序 \n"); printf("***************************\n"); printf("请选择排序方法:"); int input = 0; scanf("%d", &input); switch (input) { case 1: qsort(pc->data, pc->sz, sizeof(ProInfo), comper_name); showcontact(pc); printf("排序成功\n"); break; case 2: qsort(pc->data, pc->sz, sizeof(ProInfo), comper_age); showcontact(pc); printf("排序完成\n"); break; case 3: qsort(pc->data, pc->sz, sizeof(ProInfo), comper_sex); showcontact(pc); printf("排序完成\n"); break; default: printf("选择错误\n"); break; } } //释放空间 void Destroycontact(contact* pc) { free(pc->data); pc->data = NULL; } //保存 void Savecontact(contact* pc) { FILE* pf = fopen("contact.txt", "wb"); if (pf == NULL) { perror("fopen"); return; } int i = 0; for (i = 0; i < pc->sz; i++) { fwrite(pc->data+i, sizeof(ProInfo), 1, pf); } fclose(pf); pf = NULL; }
文件部分:
int CheckCapacity(contact* pc); void Loadcontact(contact* pc) { FILE* pf = fopen("contact.txt", "rb"); if (pf == NULL) { perror("Loadcontact"); return ; } ProInfo tmp = { 0 }; while (fread(&tmp, sizeof(ProInfo), 1, pf)) { if (0 == CheckCapacity(pc)) return; pc->data[pc->sz] = tmp; pc->sz++; } fclose(pf); pf = NULL; }
test.c
#include "FILE_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() { menu(); int input = 0; contact con; //初始化通讯录 Initcontact(&con); do { printf("请输入:\n"); scanf("%d", &input); switch (input) { case add: //添加 addconcact(&con); break; case del: //删除 delcontact(&con); break; case modfiy: //修改 modfiycontact(&con); break; case search: //查找 searchcontact(&con); break; case show: //显示 showcontact(&con); break; case sort: //排序 sortcontact(&con); break; case eit: Savecontact(&con); Destroycontact(&con); printf("退出成功\n"); break; default: printf("输入错误,请重新输入\n"); break; } } while (input); } int main() { test(); return 0; }
总结
到这里,三个版本的代码就已经写完了。其实总的来看通讯录的实现也不是很很难。就是用到了C中的结构体,动态管理和文件操作。上面的代码都是对这些知识的掌握,学懂了这三部分的内容,想必实现一个小小通讯录对你来说举手之劳罢了.