通讯录
1、需求
- 存放1000人的好友信息(名字、电话、性别、住址、年龄)
- 增加好友信息
- 删除指定名字的好友信息
- 修改好友信息
- 查找好友信息
- 显示(打印)好友信息
- 排序
2、分析
test.c 用于实现测试代码,作为程序的入口
contact.c 用于实现项目的主逻辑(函数的定义)
contact.h 函数的声明
创建好友信息(结构体类型),成员包括:名字、电话、性别、住址、年龄
声明并创建好友信息数组(1000个元素)
注:可封装数组和当前数组大小于结构体类型中
将通讯录的成员的内存设置为0
增加好友:
- 判断好友个数是否会超过数组
- 增加好友信息
- 好友个数+1
显示通讯录:遍历显示
删除好友:
查找好友:
修改好友:
排序:qsort排序
3、实现
1、页面框架搭建
- 循环显示页面:输入0-6实现退出、增加、删除等功能
enum Option
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
SHOW,
SORT
};
int main()
{
int input = 0;
do
{
PrintMenu();
input_err:
printf("请选择>: ");
scanf("%d", &input);
system("cls");
switch (input)
{
case ADD:
AddFriend(&contact);
break;
case DEL:
DeleteFriend(&contact);
break;
case SEARCH:
SearchFriend(&contact);
break;
case MODIFY:
ModifyFriend(&contact);
break;
case SHOW:
ShowContact(&contact);
break;
case SORT:
SortFriend(&contact);
break;
case EXIT:
printf("GOODBYE!\n");
break;
default:
printf("输入错误,请重新输入\n");
goto input_err;
}
} while (input);
return 0; }2、通讯录创建与初始化
定义结构体存放通讯录数据,其中成员包括好友列表和通讯录大小两个成员
好友列表可定义为结构体,其中成员包括姓名、年龄、性别、电话和住址
定义初始化函数:直接利用内存函数将结构体数组设置为0#define LIST_MAX 100define NAME_MAX 20define TELE_MAX 12define ADDR_MAX 20
typedef enum Gender
{
UNKNOWN,
MALE,
FEMALE,
}Gender;
typedef struct FriendInfo
{
char name[LIST_MAX];
int age;
Gender gender;
char tele[TELE_MAX];
char address[ADDR_MAX];
}FriendInfo;
typedef struct Contact
{
// 存放1000人信息
FriendInfo friendList[LIST_MAX];
// 列表大小
int size;
}Contact;
// 初始化通讯录
void InitContact(Contact contact_p)
{
memset(contact_p->friendList, 0, sizeof(contact_p->friendList));
contact_p->size = 0;
}
int main()
{
// 创建通讯录
Contact contact = { 0 };
// 初始化通讯录
InitContact(&contact);
return 0;
} 3、实现功能函数
1. 添加好友
注:由于添加好友的操作与修改好友的操作会涉及代码复用,故封装修改信息操作为一个函数// 修改数组元素
static void ModifyElement(Contact contact_p, int i)
{
// 增加好友信息
printf("请输入名字>: ");
scanf("%s", contact_p->friendList[i].name);
printf("请输入年龄>: ");
scanf("%d", &(contact_p->friendList[i].age));
char tmp[20] = "";
modify_friend_err:
printf("请输入性别>: ");
scanf("%s", tmp);
if (strcmp(tmp, "male") == 0)
{
contact_p->friendList[i].gender = MALE;
}
else if (strcmp(tmp, "female") == 0)
{
contact_p->friendList[i].gender = FEMALE;
}
else if (strcmp(tmp, "unknown") == 0)
{
contact_p->friendList[i].gender = UNKNOWN;
}
else
{
printf("输入错误,请重新输入\n");
goto modify_friend_err;
} printf("请输入电话>: ");
scanf("%s", contact_p->friendList.tele);
printf("请输入地址>: ");
scanf("%s", contact_p->friendList.address);
}
// 添加好友函数
void AddFriend(Contact* contact_p)
{if (contact_p->size < LIST_MAX)
{// 增加元素
ModifyElement(contact_p, contact_p->size);
// 元素+1
contact_p->size++;
printf("好友添加成功!\n");
}
else
{
printf("通讯录已满,无法继续增加\n");
} }2. 删除好友
注:由于删除、查询、修改操作会重复使用通过姓名查找元素的逻辑,故封装为一个函数,其中函数接收一个函数指针作为回调函数,以分别处理上述三种逻辑// 根据名字查找数组中的元素,并完成指定逻辑
static int FindByName(Contact contact_p, char name, void(*callback)(Contact, int))
{
int size = contact_p->size;
for (int i = 0; i < size; i++)
{
if (strcmp(name, contact_p->friendList[i].name) == 0)
{
callback(contact_p, i);
return 1;
}
}
return 0; }
// 删除好友函数中的回调函数
static void DeleteElement(Contact contact_p, int i)
{int size = contact_p->size;
// 删除元素
for (int j = i; j < size - 1; j++)
{contact_p->friendList[j] = contact_p->friendList[j + 1];
}
// 数组长度-1
contact_p->size--; }
// 删除好友函数
void DeleteFriend(Contact* contact_p)
{char input[NAME_MAX] = "";
int size = contact_p->size;
printf("请输入需要删除的好友的姓名:>");
scanf("%s", input);
int res = FindByName(contact_p, input, DeleteElement);
if (res)
{printf("删除成功!\n");
}
else
{
printf("您所输入的好友不存在\n");
} }3. 查询好友// 查找好友函数中的回调函数
static void ShowFriendInfo(const Contact contact_p, int i)
{
printf("================================\n");
printf("姓名:%s\n", contact_p->friendList[i].name);
printf("年龄:%d\n", contact_p->friendList[i].age);
switch (contact_p->friendList[i].gender)
{
case MALE:
printf("性别:男\n");
break;
case FEMALE:
printf("性别:女\n");
break;
case UNKNOWN:
printf("性别:未知\n");
break;
}
printf("电话:%s\n", contact_p->friendList[i].tele);
printf("地址:%s\n", contact_p->friendList[i].address);
printf("================================\n"); }
// 查找好友信息
void SearchFriend(Contact contact_p)
{char input[NAME_MAX] = "";
int size = contact_p->size;
printf("请输入需要查找的好友的姓名:>");
scanf("%s", input);
int res = FindByName(contact_p, input, ShowFriendInfo);
if (!res)
{printf("您所输入的好友不存在\n");
} }4. 修改好友
// 修改好友函数中的回调函数static void ModifyFriendInfo(Contact* contact_p, int i)
{printf("已找到%s,根据提示输入修改值\n", contact_p->friendList.name);
ModifyElement(contact_p, i);
}
// 修改好友信息
void ModifyFriend(Contact contact_p)
{char input[NAME_MAX] = "";
int size = contact_p->size;
printf("请输入需要修改的好友的姓名:>");
scanf("%s", input);
int res = FindByName(contact_p, input, ModifyFriendInfo);
if (res)
{
printf("修改成功!\n");
}
else
{printf("您所输入的好友不存在\n");
} }5. 显示通讯录
遍历好友列表,打印信息// 显示好友列表函数
void ShowContact(const Contact contact_p)
{
int size = contact_p->size;
if (!size)
{
printf("通讯录为空\n");
}
else
{
for (int i = 0; i < size; i++)
{
ShowFriendInfo(contact_p, i);
}
} }6. 排序
通过库函数qsort实现不同类型的快速排序// 排序函数回调
static int CompairName(const void* e1, const void e2)
{
return strcmp(((FriendInfo)e1)->name, ((FriendInfo*)e2)->name);
}
static int CompairAge(const void e1, const void e2)
{
return ((FriendInfo*)e1)->age - ((FriendInfo)e2)->age;
}
static int CompairGender(const void e1, const void* e2)
{
return ((FriendInfo)e1)->gender - ((FriendInfo)e2)->gender;
}
static int CompairTele(const void* e1, const void e2)
{
return strcmp(((FriendInfo)e1)->tele, ((FriendInfo*)e2)->tele);
}
static int CompairAddress(const void e1, const void e2)
{
return strcmp(((FriendInfo*)e1)->address, ((FriendInfo)e2)->address);
}
// 排序
void SortFriend(Contact contact_p)
{
char val[20] = "";
printf("请输入需要根据什么值进行排序(姓名、年龄、性别、电话、地址):>");
scanf("%s", val);
if (strcmp(val, "姓名") == 0)
{
qsort(contact_p->friendList,
contact_p->size,
sizeof(contact_p->friendList[0]),
CompairName);
}
else if (strcmp(val, "年龄") == 0)
{
qsort(contact_p->friendList,
contact_p->size,
sizeof(contact_p->friendList[0]),
CompairAge);
}
else if (strcmp(val, "性别") == 0)
{
qsort(contact_p->friendList,
contact_p->size,
sizeof(contact_p->friendList[0]),
CompairGender);
}
else if (strcmp(val, "电话") == 0)
{
qsort(contact_p->friendList,
contact_p->size,
sizeof(contact_p->friendList[0]),
CompairTele);
}
else if (strcmp(val, "住址") == 0)
{
qsort(contact_p->friendList,
contact_p->size,
sizeof(contact_p->friendList[0]),
CompairAddress);
}
else
{
printf("输入错误\n");
return;
}
printf("排序成功!\n"); }
4、完整代码
1、test.c文件#define _CRT_SECURE_NO_WARNINGSinclude <stdio.h>include <Windows.h>include "contact.h"
void PrintMenu()
{
printf(" 通 讯 录 \n");
printf("******************************\n");
printf("******1. ADD 2. DEL******\n");
printf("******3. SEARCH 4. MODIFY***\n");
printf("******5. SHOW 6. SORT*****\n");
printf("******************************\n");
printf("***********************0. EXIT\n");
printf("******************************\n");
}
int main()
{
int input = 0;
// 创建通讯录
Contact contact = { 0 };
// 初始化通讯录
InitContact(&contact);
do
{
PrintMenu();
input_err:
printf("请选择>: ");
scanf("%d", &input);
system("cls");
switch (input)
{
case ADD:
AddFriend(&contact);
break;
case DEL:
DeleteFriend(&contact);
break;
case SEARCH:
SearchFriend(&contact);
break;
case MODIFY:
ModifyFriend(&contact);
break;
case SHOW:
ShowContact(&contact);
break;
case SORT:
SortFriend(&contact);
break;
case EXIT:
printf("GOODBYE!\n");
break;
default:
printf("输入错误,请重新输入\n");
goto input_err;
}
} while (input); return 0;
}2、contact.h文件#pragma once
define LIST_MAX 100define NAME_MAX 20define TELE_MAX 12define ADDR_MAX 20
enum Option
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
SHOW,
SORT
};
typedef enum Gender
{
UNKNOWN,
MALE,
FEMALE,
}Gender;
typedef struct FriendInfo
{
char name[LIST_MAX];
int age;
Gender gender;
char tele[TELE_MAX];
char address[ADDR_MAX];
}FriendInfo;
typedef struct Contact
{
// 存放1000人信息
FriendInfo friendList[LIST_MAX];
// 列表大小
int size;
}Contact;
void InitContact(Contact contact_p);
void AddFriend(Contact contact_p);
void ShowContact(const Contact* contact_p);
void DeleteFriend(Contact contact_p);
void SearchFriend(Contact contact_p);
void ModifyFriend(Contact* contact_p);
void SortFriend(Contact* contact_p); 3、contact.c文件#define _CRT_SECURE_NO_WARNINGSinclude <stdio.h>include <string.h>include <stdlib.h>include "contact.h"
// *******************************************************************
// 工具函数
// *******************************************************************
// 根据名字查找数组中的元素,并完成指定逻辑
static int FindByName(Contact contact_p, char name, void(*callback)(Contact, int))
{
int size = contact_p->size;
for (int i = 0; i < size; i++)
{
if (strcmp(name, contact_p->friendList[i].name) == 0)
{
callback(contact_p, i);
return 1;
}
}
return 0; }
// 修改数组元素
static void ModifyElement(Contact contact_p, int i)
{// 增加好友信息
printf("请输入名字>: ");
scanf("%s", contact_p->friendList.name);
printf("请输入年龄>: ");
scanf("%d", &(contact_p->friendList.age));
char tmp[20] = "";
modify_friend_err:
printf("请输入性别>: ");
scanf("%s", tmp);
if (strcmp(tmp, "male") == 0)
{contact_p->friendList[i].gender = MALE;
}
else if (strcmp(tmp, "female") == 0)
{
contact_p->friendList[i].gender = FEMALE;
}
else if (strcmp(tmp, "unknown") == 0)
{
contact_p->friendList[i].gender = UNKNOWN;
}
else
{
printf("输入错误,请重新输入\n");
goto modify_friend_err;
} printf("请输入电话>: ");
scanf("%s", contact_p->friendList.tele);
printf("请输入地址>: ");
scanf("%s", contact_p->friendList.address);
}
// *******************************************************************
// *******************************************************************// 回调函数
// *******************************************************************
// 删除好友函数中的回调函数
static void DeleteElement(Contact contact_p, int i)
{int size = contact_p->size;
// 删除元素
for (int j = i; j < size - 1; j++)
{contact_p->friendList[j] = contact_p->friendList[j + 1];
}
// 数组长度-1
contact_p->size--; }
// 查找好友函数中的回调函数
static void ShowFriendInfo(const Contact contact_p, int i)
{printf("================================\n");
printf("姓名:%s\n", contact_p->friendList.name);
printf("年龄:%d\n", contact_p->friendList.age);
switch (contact_p->friendList.gender)
{
case MALE:printf("性别:男\n");
break;
case FEMALE:
printf("性别:女\n");
break;
case UNKNOWN:
printf("性别:未知\n");
break;
}
printf("电话:%s\n", contact_p->friendList[i].tele);
printf("地址:%s\n", contact_p->friendList[i].address);
printf("================================\n"); }
// 修改好友函数中的回调函数
static void ModifyFriendInfo(Contact* contact_p, int i)
{printf("已找到%s,根据提示输入修改值\n", contact_p->friendList.name);
ModifyElement(contact_p, i);
}
// 排序函数回调
static int CompairName(const void e1, const void e2)
{return strcmp(((FriendInfo*)e1)->name, ((FriendInfo)e2)->name);
}static int CompairAge(const void e1, const void* e2)
{return ((FriendInfo)e1)->age - ((FriendInfo)e2)->age;
}static int CompairGender(const void* e1, const void e2)
{return ((FriendInfo)e1)->gender - ((FriendInfo*)e2)->gender;
}static int CompairTele(const void e1, const void e2)
{return strcmp(((FriendInfo*)e1)->tele, ((FriendInfo)e2)->tele);
}static int CompairAddress(const void e1, const void* e2)
{return strcmp(((FriendInfo)e1)->address, ((FriendInfo)e2)->address);
}
// *******************************************************************
// *******************************************************************// 主功能函数
// *******************************************************************
// 初始化通讯录
void InitContact(Contact contact_p)
{memset(contact_p->friendList, 0, sizeof(contact_p->friendList));
contact_p->size = 0;
}
// 添加好友函数
void AddFriend(Contact contact_p)
{if (contact_p->size < LIST_MAX)
{// 增加元素
ModifyElement(contact_p, contact_p->size);
// 元素+1
contact_p->size++;
printf("好友添加成功!\n");
}
else
{
printf("通讯录已满,无法继续增加\n");
} }
// 显示好友列表函数
void ShowContact(const Contact* contact_p)
{int size = contact_p->size;
if (!size)
{printf("通讯录为空\n");
}
else
{
for (int i = 0; i < size; i++)
{
ShowFriendInfo(contact_p, i);
}
} }
// 删除好友函数
void DeleteFriend(Contact contact_p)
{char input[NAME_MAX] = "";
int size = contact_p->size;
printf("请输入需要删除的好友的姓名:>");
scanf("%s", input);
int res = FindByName(contact_p, input, DeleteElement);
if (res)
{printf("删除成功!\n");
}
else
{
printf("您所输入的好友不存在\n");
} }
// 查找好友信息
void SearchFriend(Contact contact_p)
{char input[NAME_MAX] = "";
int size = contact_p->size;
printf("请输入需要查找的好友的姓名:>");
scanf("%s", input);
int res = FindByName(contact_p, input, ShowFriendInfo);
if (!res)
{printf("您所输入的好友不存在\n");
} }
// 修改好友信息
void ModifyFriend(Contact* contact_p)
{char input[NAME_MAX] = "";
int size = contact_p->size;
printf("请输入需要修改的好友的姓名:>");
scanf("%s", input);
int res = FindByName(contact_p, input, ModifyFriendInfo);
if (res)
{
printf("修改成功!\n");
}
else
{printf("您所输入的好友不存在\n");
} }
// 排序
void SortFriend(Contact* contact_p)
{char val[20] = "";
printf("请输入需要根据什么值进行排序(姓名、年龄、性别、电话、地址):>");
scanf("%s", val);
if (strcmp(val, "姓名") == 0)
{qsort(contact_p->friendList,
contact_p->size,
sizeof(contact_p->friendList[0]),
CompairName);
}
else if (strcmp(val, "年龄") == 0)
{
qsort(contact_p->friendList,
contact_p->size,
sizeof(contact_p->friendList[0]),
CompairAge);
}
else if (strcmp(val, "性别") == 0)
{
qsort(contact_p->friendList,
contact_p->size,
sizeof(contact_p->friendList[0]),
CompairGender);
}
else if (strcmp(val, "电话") == 0)
{
qsort(contact_p->friendList,
contact_p->size,
sizeof(contact_p->friendList[0]),
CompairTele);
}
else if (strcmp(val, "住址") == 0)
{
qsort(contact_p->friendList,
contact_p->size,
sizeof(contact_p->friendList[0]),
CompairAddress);
}
else
{
printf("输入错误\n");
return;
}
printf("排序成功!\n"); }
|