停步小憩,且闻花香。
---------《寻找天堂》
目录
文章目录
一、通讯录介绍
二、 通讯录的实现过程:
2.1 通讯录的菜单栏
2.2 定义人的信息(定义存储个人信息的结构体)
2.3 定义通讯录的信息
2.4 创建通讯录并且初始化
2.5 添加联系人的信息
2.6 显示通讯录的信息
2.7 删除联系人的信息
编辑
2.8 查找联系人的信息
2.9 修改联系人的信息
2.10 排序联系人的信息—按名字排序
2.11 销毁通讯录
三、完整代码
contact.h
contact.c
test.c
通讯录是记录和存储联系人信息的电子或纸质文件,用于方便用户查找和联系他人。小时候见过的纸质通讯录,是一个小本子,用户可以手动在其中写下联系人的姓名、电话号码、地址等信息。本篇文章介绍这种通讯录的电子版本。这个电子版本的通讯录实现以下功能:
可以保存100个人的信息 人的信息:
1.添加联系人信息; 名字
2.删除联系人信息; 年龄
3.查找联系人信息; 电话
4.修改联系人信息; 地址
5.显示联系人信息; 性别
6.排序联系人信息;
0.退出程序
这里将通讯录分为三个模块实现:
test.c用于测试通讯录功能
contact.c用于实现通讯录具体功能
contact.h用于实现接口的声明
void menu()
{
printf("***************菜单****************\n");
printf("****** 1.add 2.del ******\n");
printf("****** 3.search 4.modify ******\n");
printf("****** 5.sort 6.show ******\n");
printf("****** 0.exit ******\n");
printf("***********************************\n");
}
用户选项 ,进行对应功能的选择,此处使用了枚举,让选项更加清晰易懂
enum Option
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
SORT,
SHOW
};
当用户输入对应的选项时,执行对应的功能,使用选择结构进行控制
void test()
{
int input = 0;
do
{
menu();
printf("请选择->");
scanf("%d", &input);
switch (input)
{
case ADD:
//增加联系人
break;
case DEL:
//删除联系人
break;
case SEARCH:
//查找联系人
break;
case MODIFY:
//修改联系人
break;
case SORT:
//对通讯录进行排序(按名字)
break;
case SHOW:
//显示联系人
break;
case EXIT:
printf("退出通讯录\n");
break;
default:
printf("选择错误,请重新选择!\n");
break;
}
} while (input);
}
#define NAME_MAX 20
#define SEX_MAX 5
#define ADDR_MAX 30
#define NUMBER_MAX 12
#define DEFAULT_SZ 3
typedef struct PeoInfo
{
char name[NAME_MAX];
int age;
char number[NUMBER_MAX];
char adress[ADDR_MAX];
char sex[SEX_MAX];
}PeoInfo;
画图展示人的信息的结构体如下,比较形象地展示
通讯录不能只存储一个人的信息吧,所以这里还需要定义一个通讯录的结构体,来存储更多人的信息,这里用单链表的结构把每个人的信息连接起来,通过下面的图,比较清晰地展示一下
typedef struct Contact
{
PeoInfo* data;//存放数据
int capacity;//当前通讯录容量
int sz;//实际有效信息数量
}Contact;
通讯录的信息已经在contact.h定义好,我们需要在test.c创建并且给它初始化
//初始化通讯录
void InitContact(Contact* pc)
{
assert(pc); //不能传递空指针,强制断言
pc->sz = 0; //通讯录的有效信息数量置0
//#define DEFAULT_SZ 3 在contact.h定义了,默认存储3个人的信息
PeoInfo *tmp = (PeoInfo*)malloc(DEFAULT_SZ *sizeof(PeoInfo)); //开空间
if (tmp != NULL)
{
pc->data = tmp;
}
else //如果malloc开空间失败,打印错误信息,一般不会
{
printf("InitContact()::%s\n", strerror(errno));
return;
}
pc->capacity = DEFAULT_SZ; //当前通讯录容量
}
通讯录初始化后, 运行看看,发现PeoInfo里的数据为随机值,这里只是开了空间,没有初始化里面的数据
//增加联系人
void AddContact(Contact* pc)
{
assert(pc);
int i=addcapacity(pc);
if (i)
{
printf("请输入姓名->");
scanf("%s", pc->data[pc->sz].name);
printf("请输入性别->");
scanf("%s", pc->data[pc->sz].sex);
printf("请输入年龄->");
scanf("%d", &(pc->data[pc->sz].age));
printf("请输入住址->");
scanf("%s", pc->data[pc->sz].adress);
printf("请输入电话->");
scanf("%s", pc->data[pc->sz].number);
pc->sz++;
printf("添加联系人成功!\n");
}
else
{
printf("AddContact::%s\n", strerror(errno));
}
}
由于初始通讯录的时候,默认存储三个人的信息,随着通讯录里面的联系人不断增加,必然会超出这个默认值,所以此时通讯录需要进行扩容
//判断是否增容
int addcapacity(Contact* pc)
{
assert(pc);
//判断一下通讯录是否满了
if (pc->sz == pc->capacity) //满了进行扩容
{ //relloc扩容后会复制原来的数据,一次加两个人的空间
PeoInfo* tmp = (PeoInfo*)realloc(pc->data, sizeof(PeoInfo)*(pc->capacity+ 2));
if (tmp != NULL)
{
pc->data = tmp;
pc->capacity += 2;
//printf("增容成功\n");
return 1;
}
else
{
printf("addcapacity()::%s\n", strerror(errno));
return 0;
}
}
return 1;
}
添加完联系人后,想查看里面到目前为止存了哪些联系人,所以需要一个展示通讯录的功能
void ShowContact(Contact* pc)//显示通讯录
{
assert(pc);
if (pc->sz == 0)
{
printf("通讯录里无联系人!\n");
}
else
{
int i = 0;
printf("%-7s\t%-7s\t%-6s\t%-20s\t%-15s\n", "姓名", "性别", "年龄", "住址", "电话");
for (i = 0; i < pc->sz; i++)
{
printf("%-7s\t%-7s\t%-6d\t%-20s\t%-15s\n",
pc->data[i].name, pc->data[i].sex, pc->data[i].age,
pc->data[i].adress, pc->data[i].number);
}
}
}
删除联系人的步骤,先找到该联系人是否存在,不存在则不执行删除操作,并打印“没有找到您需要删除的人!”;存在则返回该联系人对应的下标 ,删除程序拿到这个下标,从后往前进行覆盖,那么这个联系人就不存在 ====> 被删除啦
int FindPeoInfo(char* name, Contact* pc)//查找联系人,返回其下标
{
int i = 0;
for (i = 0; i < pc->sz; i++)
{
if (*name == *(pc->data[i].name))
{
return i;
}
}
return -1;
}
void DeleteContact(Contact* pc)//删除联系人
{
char name[NAME_MAX] = "0";
int i = 0;
printf("请输入要删除的联系人姓名->");
scanf("%s", name);
//查找联系人
int flag=FindPeoInfo(name,pc);
if (flag != -1)
{
for (i = flag; i < pc->sz-1; i++)
{
pc->data[i] = pc->data[i + 1];
}
pc->sz--;
printf("删除成功!\n");
}
else
{
printf("没有找到您需要删除的人!\n");
}
}
查找联系人的信息的思路:先查找出来 再打印出来
void FindContact(Contact* pc)//查找联系人
{
char name[NAME_MAX] = "0";
printf("请输入要查找的联系人姓名->");
scanf("%s", name);
int flag = FindPeoInfo(name, pc);
if (flag != -1)
{
printf("%-7s\t%-7s\t%-6s\t%-20s\t%-15s\n", "姓名", "性别", "年龄", "住址", "电话");
printf("%-7s\t%-7s\t%-6d\t%-20s\t%-15s\n",
pc->data[flag].name, pc->data[flag].sex, pc->data[flag].age,
pc->data[flag].adress, pc->data[flag].number);
}
else
{
printf("查无此人!\n");
}
}
修改联系人的信息的思路跟查找联系人的信息的思路,差不多:先查找出来 再进行修改
void ModifyContact(Contact* pc)//修改联系人
{
char name[NAME_MAX] = "0";
printf("请输入要修改的联系人姓名->");
scanf("%s", name);
int flag = FindPeoInfo(name, pc);
if (flag == -1)
{
printf("查无此人\n");
return;
}
else
{
int input = 0;
do
{
/*char rename[NAME_MAX] = "0";
int reage = 0;
char resex[] = "0";
char readdress[] = "0";
char*/
printf("1.姓名 2.年龄 3.性别 4.住址 5.电话 0.退出\n");
printf("请输入要修改的选项(按0退出修改)->");
scanf("%d", &input);
switch (input)
{
case 1:
printf("请输入改正后的姓名->");
scanf("%s", pc->data[flag].name);
break;
case 2:
printf("请输入改正后的年龄->");
scanf("%d", &(pc->data[flag].age));
break;
case 3:
printf("请输入改正后的性别->");
scanf("%s", pc->data[flag].sex);
break;
case 4:
printf("请输入改正后的住址->");
scanf("%s", pc->data[flag].adress);
break;
case 5:
printf("请输入改正后的电话->");
scanf("%s", pc->data[flag].number);
break;
case 0:
break;
default:
printf("输入错误,请重新输入!\n");
break;
}
} while(input);
printf("修改成功!\n");
}
}
//对联系人进行排序(按名字)
int compare_Peo(const void* e1, const void* e2)
{
return strcmp(((PeoInfo*)e1)->name,((PeoInfo*)e2)->name);
}
void SortContact(Contact* pc)
{
qsort(pc->data, pc->sz, sizeof(pc->data[0]), compare_Peo);
printf("排序成功\n");
ShowContact(pc);
}
由于通讯录建立中开辟了空间,为了避免内存泄漏,在退出通讯录之前,需要释放开辟的空间
void DestroyContact(Contact* pc)//空间销毁
{
free(pc->data);
pc->data = NULL;
pc->capacity = 0;
pc->sz = 0;
}
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
#include
//#define MAX_SIZE 10
#define NAME_MAX 20
#define SEX_MAX 5
#define ADDR_MAX 30
#define NUMBER_MAX 12
#define DEFAULT_SZ 3
typedef struct PeoInfo
{
char name[NAME_MAX];
int age;
char number[NUMBER_MAX];
char adress[ADDR_MAX];
char sex[SEX_MAX];
}PeoInfo;
typedef struct Contact
{
PeoInfo* data;//存放数据
int capacity;//当前通讯录容量
int sz;//实际有效信息数量
}Contact;
void InitContact(Contact* pc);//初始化通讯录
void AddContact(Contact* pc);//增加联系人
void ShowContact(Contact* pc);//显示通讯录
void DeleteContact(Contact* pc);//删除联系人
int FindPeoInfo(char* name, Contact* pc);//查找联系人,返回其下标
void FindContact(Contact* pc);//查找联系人
void ModifyContact(Contact* pc);//修改联系人
void SortContact(Contact* pc);//对联系人进行排序(按名字)
int addcapacity(Contact* pc);//增容
void DestroyContact(Contact* pc);//销毁通讯录
#include"contact.h"
//初始化通讯录
void InitContact(Contact* pc)
{
assert(pc);
pc->sz = 0;
PeoInfo *tmp = (PeoInfo*)malloc(DEFAULT_SZ *sizeof(PeoInfo));
if (tmp != NULL)
{
pc->data = tmp;
}
else
{
printf("InitContact()::%s\n", strerror(errno));
return;
}
pc->capacity = DEFAULT_SZ;
}
//判断是否增容
int addcapacity(Contact* pc)
{
assert(pc);
if (pc->sz == pc->capacity)
{
PeoInfo* tmp = (PeoInfo*)realloc(pc->data, sizeof(PeoInfo)*(pc->capacity+ 2));
if (tmp != NULL)
{
pc->data = tmp;
pc->capacity += 2;
//printf("增容成功\n");
return 1;
}
else
{
printf("addcapacity()::%s\n", strerror(errno));
return 0;
}
}
return 1;
}
//增加联系人
void AddContact(Contact* pc)
{
assert(pc);
int i=addcapacity(pc);
if (i)
{
printf("请输入姓名->");
scanf("%s", pc->data[pc->sz].name);
printf("请输入性别->");
scanf("%s", pc->data[pc->sz].sex);
printf("请输入年龄->");
scanf("%d", &(pc->data[pc->sz].age));
printf("请输入住址->");
scanf("%s", pc->data[pc->sz].adress);
printf("请输入电话->");
scanf("%s", pc->data[pc->sz].number);
pc->sz++;
printf("添加联系人成功!\n");
}
else
{
printf("AddContact::%s\n", strerror(errno));
}
}
void ShowContact(Contact* pc)//显示通讯录
{
assert(pc);
if (pc->sz == 0)
{
printf("通讯录里无联系人!\n");
}
else
{
int i = 0;
printf("%-7s\t%-7s\t%-6s\t%-20s\t%-15s\n", "姓名", "性别", "年龄", "住址", "电话");
for (i = 0; i < pc->sz; i++)
{
printf("%-7s\t%-7s\t%-6d\t%-20s\t%-15s\n",
pc->data[i].name, pc->data[i].sex, pc->data[i].age,
pc->data[i].adress, pc->data[i].number);
}
}
}
int FindPeoInfo(char* name, Contact* pc)//查找联系人,返回其下标
{
int i = 0;
for (i = 0; i < pc->sz; i++)
{
if (*name == *(pc->data[i].name))
{
return i;
}
}
return -1;
}
void DeleteContact(Contact* pc)//删除联系人
{
char name[NAME_MAX] = "0";
int i = 0;
printf("请输入要删除的联系人姓名->");
scanf("%s", name);
//查找联系人
int flag=FindPeoInfo(name,pc);
if (flag != -1)
{
for (i = flag; i < pc->sz-1; i++)
{
pc->data[i] = pc->data[i + 1];
}
pc->sz--;
printf("删除成功!\n");
}
else
{
printf("没有找到您需要删除的人!\n");
}
}
void FindContact(Contact* pc)//查找联系人
{
char name[NAME_MAX] = "0";
printf("请输入要查找的联系人姓名->");
scanf("%s", name);
int flag = FindPeoInfo(name, pc);
if (flag != -1)
{
printf("%-7s\t%-7s\t%-6s\t%-20s\t%-15s\n", "姓名", "性别", "年龄", "住址", "电话");
printf("%-7s\t%-7s\t%-6d\t%-20s\t%-15s\n",
pc->data[flag].name, pc->data[flag].sex, pc->data[flag].age,
pc->data[flag].adress, pc->data[flag].number);
}
else
{
printf("查无此人!\n");
}
}
void ModifyContact(Contact* pc)//修改联系人
{
char name[NAME_MAX] = "0";
printf("请输入要修改的联系人姓名->");
scanf("%s", name);
int flag = FindPeoInfo(name, pc);
if (flag == -1)
{
printf("查无此人\n");
return;
}
else
{
int input = 0;
do
{
/*char rename[NAME_MAX] = "0";
int reage = 0;
char resex[] = "0";
char readdress[] = "0";
char*/
printf("1.姓名 2.年龄 3.性别 4.住址 5.电话 0.退出\n");
printf("请输入要修改的选项(按0退出修改)->");
scanf("%d", &input);
switch (input)
{
case 1:
printf("请输入改正后的姓名->");
scanf("%s", pc->data[flag].name);
break;
case 2:
printf("请输入改正后的年龄->");
scanf("%d", &(pc->data[flag].age));
break;
case 3:
printf("请输入改正后的性别->");
scanf("%s", pc->data[flag].sex);
break;
case 4:
printf("请输入改正后的住址->");
scanf("%s", pc->data[flag].adress);
break;
case 5:
printf("请输入改正后的电话->");
scanf("%s", pc->data[flag].number);
break;
case 0:
break;
default:
printf("输入错误,请重新输入!\n");
break;
}
} while(input);
printf("修改成功!\n");
}
}
//对联系人进行排序(按名字)
int compare_Peo(const void* e1, const void* e2)
{
return strcmp(((PeoInfo*)e1)->name,((PeoInfo*)e2)->name);
}
void SortContact(Contact* pc)
{
qsort(pc->data, pc->sz, sizeof(pc->data[0]), compare_Peo);
printf("排序成功\n");
ShowContact(pc);
}
void DestroyContact(Contact* pc)//空间销毁
{
free(pc->data);
pc->data = NULL;
pc->capacity = 0;
pc->sz = 0;
}
#include"contact.h"
enum Option
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
SORT,
SHOW
};
void menu()
{
printf("***************菜单****************\n");
printf("****** 1.add 2.del ******\n");
printf("****** 3.search 4.modify ******\n");
printf("****** 5.sort 6.show ******\n");
printf("****** 0.exit ******\n");
printf("***********************************\n");
}
void test()
{
Contact con;
InitContact(&con);//初始化通讯录
int input = 0;
do
{
menu();
printf("请选择->");
scanf("%d", &input);
switch (input)
{
case ADD:
//增加联系人
AddContact(&con);
break;
case DEL:
//删除联系人
DeleteContact(&con);
break;
case SEARCH:
//查找联系人
FindContact(&con);
break;
case MODIFY:
//修改联系人
ModifyContact(&con);
break;
case SORT:
//对通讯录进行排序(按名字)
SortContact(&con);
break;
case SHOW:
//显示联系人
ShowContact(&con);
break;
case EXIT:
DestroyContact(&con);
printf("退出通讯录\n");
break;
default:
printf("选择错误,请重新选择!\n");
break;
}
} while (input);
}
int main()
{
test();
return 0;
}
若有不足之处,望各位大佬多多指教