作者主页:paper jie的博客_CSDN博客
本文作者:大家好,我是paper jie,感谢你阅读本文,欢迎一建三连哦。
本文录入于《C语言》专栏,本专栏是针对于大学生,编程小白精心打造的。笔者用重金(时间和精力)打造,将基础知识一网打尽,希望可以帮到读者们哦。
其他专栏:《算法详解》《系统解析C语言》《C语言-语法篇》等
内容分享:本期将用C的知识来通讯录 将分为三个版本
目录
前言
基本要求
通讯录实现思想
通讯录的构成
设计思路
具体代码
静态版本
contact.h
contact.c
test.c
动态版本
malloc_contact.h
malloc_contact.c
malloc_test.c
文件版本
FILE_contact.h
FILE_contact.c
test.c
总结
在我们的日藏生活中,经常会通过手机来互相联系交流,而我们常常会把常联系的电话号码添加进我们的通讯录里面。它是一种利用互联网或实现通讯录信息同步更新和备份的应用,服务。你可以在个人电脑、移动电话等任何联网设备上录入你的联系人的手机,通信地址等通讯录信息,或对以前的信息进行分组、管理和更新,在你的许可下,该联系人可以看到他所在组内的其他联系人信息,从而实现通讯录共享,如果该联系人更新自己的联系信息,你的通讯录会自动更新,实现同步通讯录,并留下旧版本的通讯录信息。但这里的原理和代码是怎么样的我们就不得而知了。今天我们就通过C来编写通讯录的后端代码,我们将分为三个版本来实现,由易到难,干货满满,大家放心食用。
通讯录可以存储多个人的信息,信息需要包括:姓名 年龄 性别 地址 电话
功能:
添加新增联系人
删除不需要的联系人
查找联系人
修改联系人信息
查看所有联系人信息
可以对联系人进行排序
为了让代码不会太过冗余,这里将用三个文件test.c contact.c contact.h 来存放代码. test.c用于来测试我们的代码, contact.c来实现通讯录需要的函数代码,contact.h用来存放函数的声明和头文件包含。
添加一个菜单提示用户如何使用
让通讯录可以多次使用
设置一个合理的变量为通讯录,对通讯录进行初始化
实现功能所需要的函数
#include
#include
#include
#include
#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);
#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;
}
}
#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;
}
上面的版本我们发现通讯录是固定的,添加满后不能继续添加,我们需要设计一个可以增容的代码。
#include
#include
#include
#include
#include
#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);
#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;
}
#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;
}
上面的代码虽然可以实现增容,但是可以发现一旦程序退出后,下次代码再运行起来上一次的数据就丢失了。我们需要一个可以一直保存数据的代码。
#include
#include
#include
#include
#include
#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);
#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;
}
#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中的结构体,动态管理和文件操作。上面的代码都是对这些知识的掌握,学懂了这三部分的内容,想必实现一个小小通讯录对你来说举手之劳罢了。