文章目录
1. 通讯录模拟实现
将通讯录的模拟实现分成三部分
主函数部分 头文件函数声明部分 函数实现部分
1.1主函数部分
1.1.1静态版本
#define _CRT_SECURE_NO_WARNINGS 1
#include"contact.h"
void menu()//菜单
{
printf("*********************************\n");
printf("*****1.add 2.del *****\n");
printf("*****3.search 4.modify*****\n");
printf("*****5.show 6.sort *****\n");
printf("*****0.exit *****\n");
printf("*********************************\n");
printf("*********************************\n");
}
enum option//枚举 增加代码的可读性和可维护性
{
EXIT,
add,
del,
search,
modify,
show,
sort,
};
int main()
{
int input = 0;
struct contact con;//创建通讯录
intcontact(&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 show:
showcontact(&con);
break;
case sort:
sortcontact(&con);
break;
case EXIT:
printf("退出通讯录");
break;
default:
printf("重新选择");
break;
}
} while (input);
return 0;
}
1.1.2动态版本
#define _CRT_SECURE_NO_WARNINGS 1
#include"contact.h"
void menu()
{
printf("*********************************\n");
printf("*****1.add 2.del *****\n");
printf("*****3.search 4.modify*****\n");
printf("*****5.show 6.sort *****\n");
printf("*****0.exit *****\n");
printf("*********************************\n");
printf("*********************************\n");
}
enum option
{
EXIT,
add,
del,
search,
modify,
show,
sort,
};
int main()
{
int input = 0;
struct contact con;//创建通讯录
intcontact(&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 show:
showcontact(&con);
break;
case sort:
sortcontact(&con);
break;
case EXIT:
destroycontact(&con);
printf("退出通讯录");
break;
default:
printf("重新选择");
break;
}
} while (input);
return 0;
}
枚举部分可以看我写的枚举声明
1.1.3存储数据版本
#define _CRT_SECURE_NO_WARNINGS 1
#include"contact.h"
void menu()
{
printf("*********************************\n");
printf("*****1.add 2.del *****\n");
printf("*****3.search 4.modify*****\n");
printf("*****5.show 6.sort *****\n");
printf("*****0.exit *****\n");
printf("*********************************\n");
printf("*********************************\n");
}
enum option
{
EXIT,
add,
del,
search,
modify,
show,
sort,
};
int main()
{
int input = 0;
struct contact con;//创建通讯录
intcontact(&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 show:
showcontact(&con);
break;
case sort:
sortcontact(&con);
break;
case EXIT:
savecontact(&con);
destroycontact(&con);
printf("退出通讯录");
break;
default:
printf("重新选择");
break;
}
} while (input);
return 0;
}
1.2函数声明部分
1.2.1静态版本
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>
#define max 100 //声明变量方便修改
#define maxname 20
#define maxsex 5
#define maxtele 20
#define maxaddr 30
struct peoinfo//定义结构体类型
{
char name[maxname];
char sex[maxsex];
char tele[maxtele];
int age;
char addr[maxaddr];
};
struct contact //通讯录是由成员和下标组和而成,所以再次定义结构体
{
struct peoinfo date[max];
int sz;
};
//清空通讯录
void intcontact(struct contact*pc);
//添加成员
void addcontact(struct contact*pc);
//显示成员
void showcontact(const struct contact*pc);
//删除成员
void delcontact(struct contact* pc);
//查找成员
void searchcontact(const struct contact* pc);
//修改成员
void modifycontact( struct contact* pc);
//排序成员
void sortcontact(struct contact* pc);
1.2.2动态版本
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>
#define max 100
#define maxname 20
#define maxsex 5
#define maxtele 20
#define maxaddr 30
#define CAPACITY_SZ 3
#define sc 2
struct peoinfo
{
char name[maxname];
char sex[maxsex];
char tele[maxtele];
int age;
char addr[maxaddr];
};
//静态版本
//struct contact
//{
// struct peoinfo date[max];
// int sz;
//};
//动态版本
struct contact
{
struct peoinfo* date;//指向存放数据的空间
int sz;//已经放进的信息
int capacity;//容量
};
void intcontact(struct contact*pc);
void addcontact(struct contact*pc);
void showcontact(const struct contact*pc);
void delcontact(struct contact* pc);
void searchcontact(const struct contact* pc);
void modifycontact(struct contact*pc);
void sortcontact(struct contact* pc);
void destorycontact(struct contact* pc);
1.2.3存储数据版本
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>
#define max 100
#define maxname 20
#define maxsex 5
#define maxtele 20
#define maxaddr 30
#define CAPACITY_SZ 3
#define sc 2
struct peoinfo
{
char name[maxname];
char sex[maxsex];
char tele[maxtele];
int age;
char addr[maxaddr];
};
//静态版本
//struct contact
//{
// struct peoinfo date[max];
// int sz;
//};
//动态版本
struct contact
{
struct peoinfo* date;//指向存放数据的空间
int sz;//已经放进的信息
int capacity;//容量
};
void intcontact(struct contact*pc);
void addcontact(struct contact*pc);
void showcontact(const struct contact*pc);
void delcontact(struct contact* pc);
void searchcontact(const struct contact* pc);
void modifycontact(struct contact*pc);
void sortcontact(struct contact* pc);
void destroycontact(struct contact* pc);
void savecontact(struct contact*pc);
//加载文件信息到通讯录
void loadcontact(struct contact* pc);
1.3 函数实现部分
1.3.1静态版本
#define _CRT_SECURE_NO_WARNINGS 1
#include"contact.h"
// 清空通讯录
void intcontact(struct contact *pc)
{
assert(pc);//断言排除空指针
pc->sz = 0;
memset(pc->date, 0, 100 * sizeof(struct peoinfo));//置零
}
//添加联系人
void addcontact(struct contact* pc)
{
assert(pc);
if (pc->sz == 100)//判断通讯录是否满了
{
printf("通讯录已满,无法添加\n");
return;
}
printf("请输入名字");
scanf("%s", pc->date[pc->sz].name);
printf("请输入性别");
scanf("%s", pc->date[pc->sz].sex);
printf("请输入年龄");
scanf("%d", &(pc->date[pc->sz].age));
printf("请输入电话");
scanf("%s", pc->date[pc->sz].tele);
printf("请输入地址");
scanf("%s", pc->date[pc->sz].addr);
pc->sz++;//输入结束后数字表示有多少成员,再加1
printf("成功添加联系人\n");
}
//显示通讯录成员
void showcontact(const struct contact* pc)
{
int i = 0;
printf("%20s\t%5s\t%5s\t%12s\t%30s\n","姓名","性别","年龄","电话","地址");//水平制表让输出结果看起来对齐规整
for (i = 0; i < pc->sz; i++)
printf("%20s\t%5s\t%5d\t%12s\t%30s\n", pc->date[i].name,
pc->date[i].sex,
pc->date[i].age,
pc->date[i].tele,
pc->date[i].addr);
}
//查找成员并返回下标
static int find_name(const struct contact* pc,char name[])
{
int i = 0;
for (i = 0; i < pc->sz; i++)
{
if (0 == strcmp(pc->date[i].name, name))//strcmp函数比骄字符串
{
return i;
}
}
return -1;
}
//删除通讯录成员
void delcontact(struct contact* pc)
{
char name[maxname];
printf("请输入要删除人的名字");
scanf("%s", name);
int ret=find_name(pc, name);查找要删除的成员
if (ret == -1)
printf("要删除的人不存在\n");
else//删除联系人只需要被覆盖,用后面的联系人依次覆盖
{
int j = 0;
for (j = ret; j < pc->sz-1; j++)//加入总共7个元素,那么其最大下标为6,进而j的最大值就是5,所以就j<6,也就是pc->sz-1
{
pc->date[j] = pc->date[j + 1];
}
pc->sz--;//最后成员数减一
printf("成功删除指定联系人\n");
}
}
//查找通讯录成员
void searchcontact(const struct contact*pc)
{
char name[maxname];
printf("请输入要查找人的名字");
scanf("%s", name);
int ret = find_name(pc, name);
if (ret == -1)
printf("要查找的人不存在\n");
else
{
printf("%20s\t%5s\t%5s\t%12s\t%30s\n", "姓名", "性别", "年龄", "电话", "地址");
//这里只需要把打印的函数搬过来,将下标改为ret
printf("%20s\t%5s\t%5d\t%12s\t%30s\n", pc->date[ret].name,
pc->date[ret].sex,
pc->date[ret].age,
pc->date[ret].tele,
pc->date[ret].addr);
}
}
//修改成员
void modifycontact(struct contact* pc)
{
char name[maxname];
printf("请输入要修改人的名字");
scanf("%s", name);
int ret = find_name(pc, name);
if (ret == -1)
printf("要查找的人不存在\n");
else
{
//同理输入部分搬过来改变下标为ret
printf("请输入名字");
scanf("%s", pc->date[ret].name);
printf("请输入性别");
scanf("%s", pc->date[ret].sex);
printf("请输入年龄");
scanf("%d", &(pc->date[ret].age));
printf("请输入电话");
scanf("%s", pc->date[ret].tele);
printf("请输入地址");
scanf("%s", pc->date[ret].addr);
printf("修改成功\n");
}
}
//排序我们使用qsort函数
int cmpage(const void* e1, const void* e2)
{
return((struct peoinfo*)e1)->age - ((struct peoinfo*)e2)->age;
//将e1e2强转为struct peoinfo*,要通过什么排序就指向什么,我这里使用的年龄
}
void sortcontact(struct contact* pc)
{
qsort(pc->date, pc->sz, sizeof(struct peoinfo), cmpage);
//传地址首元素,数量,单个元素大小,函数
printf("按年龄排序成功");
}
1.3.2动态版本
在这里插入代码片#define _CRT_SECURE_NO_WARNINGS 1
#include"contact.h"
//静态初始化
//void intcontact(struct contact *pc)
//{
// assert(pc);
// pc->sz = 0;
// memset(pc->date, 0, 100 * sizeof(struct peoinfo));
//}
//动态版本
void intcontact(struct contact* pc)
{
assert(pc);
pc->date = (struct peoinfo*)malloc(CAPACITY_SZ * sizeof(struct peoinfo));
if (pc->date == NULL)
{
perror("intcontact()");
}
pc->sz = 0;
pc->capacity = CAPACITY_SZ;
}
//静态版本
//void addcontact(struct contact* pc)
//{
// assert(pc);
// if (pc->sz == 100)
// {
// printf("通讯录已满,无法添加\n");
// return;
// }
// printf("请输入名字");
// scanf("%s", pc->date[pc->sz].name);
// printf("请输入性别");
// scanf("%s", pc->date[pc->sz].sex);
// printf("请输入年龄");
// scanf("%d", &(pc->date[pc->sz].age));
// printf("请输入电话");
// scanf("%s", pc->date[pc->sz].tele);
// printf("请输入地址");
// scanf("%s", pc->date[pc->sz].addr);
// pc->sz++;
// printf("成功添加联系人\n");
//}
//动态版本
int checkcapacity(struct contact* pc)
{
if (pc->sz == pc->capacity)
{
struct peoinfo* ptr = (struct peoinfo*)realloc(pc->date, (pc->capacity + sc) * sizeof(struct peoinfo));
if (ptr != NULL)
{
pc->date = ptr;
pc->capacity += sc;
printf("增容成功\n");
return 1;
}
else
{
perror("addcontact()");
return 0;
}
}
else
return 1;
}
void addcontact(struct contact* pc)
{
assert(pc);
if (0 == checkcapacity(pc))
{
return;
}
printf("请输入名字");
scanf("%s", pc->date[pc->sz].name);
printf("请输入性别");
scanf("%s", pc->date[pc->sz].sex);
printf("请输入年龄");
scanf("%d", &(pc->date[pc->sz].age));
printf("请输入电话");
scanf("%s", pc->date[pc->sz].tele);
printf("请输入地址");
scanf("%s", pc->date[pc->sz].addr);
pc->sz++;
printf("成功添加联系人\n");
}
void showcontact(const struct contact* pc)
{
int i = 0;
printf("%20s\t%5s\t%5s\t%12s\t%30s\n","姓名","性别","年龄","电话","地址");
for (i = 0; i < pc->sz; i++)
printf("%20s\t%5s\t%5d\t%12s\t%30s\n", pc->date[i].name,
pc->date[i].sex,
pc->date[i].age,
pc->date[i].tele,
pc->date[i].addr);
}
static int find_name(const struct contact* pc,char name[])
{
int i = 0;
for (i = 0; i < pc->sz; i++)
{
if (0 == strcmp(pc->date[i].name, name))
{
return i;
}
}
return -1;
}
void delcontact(struct contact* pc)
{
char name[maxname];
printf("请输入要删除人的名字");
scanf("%s", name);
int ret=find_name(pc, name);
if (ret == -1)
printf("要删除的人不存在\n");
else
{
int j = 0;
for (j = ret; j < pc->sz-1; j++)
{
pc->date[j] = pc->date[j + 1];
}
pc->sz--;
printf("成功删除指定联系人\n");
}
}
void searchcontact(const struct contact*pc)
{
char name[maxname];
printf("请输入要查找人的名字");
scanf("%s", name);
int ret = find_name(pc, name);
if (ret == -1)
printf("要查找的人不存在\n");
else
{
printf("%20s\t%5s\t%5s\t%12s\t%30s\n", "姓名", "性别", "年龄", "电话", "地址");
printf("%20s\t%5s\t%5d\t%12s\t%30s\n", pc->date[ret].name,
pc->date[ret].sex,
pc->date[ret].age,
pc->date[ret].tele,
pc->date[ret].addr);
}
}
void modifycontact(struct contact* pc)
{
char name[maxname];
printf("请输入要修改人的名字");
scanf("%s", name);
int ret = find_name(pc, name);
if (ret == -1)
printf("要查找的人不存在\n");
else
{
printf("请输入名字");
scanf("%s", pc->date[ret].name);
printf("请输入性别");
scanf("%s", pc->date[ret].sex);
printf("请输入年龄");
scanf("%d", &(pc->date[ret].age));
printf("请输入电话");
scanf("%s", pc->date[ret].tele);
printf("请输入地址");
scanf("%s", pc->date[ret].addr);
printf("修改成功\n");
}
}
int cmpage(const void* e1, const void* e2)
{
return((struct peoinfo*)e1)->age - ((struct peoinfo*)e2)->age;
}
void sortcontact(struct contact* pc)
{
qsort(pc->date, pc->sz, sizeof(struct peoinfo), cmpage);
printf("按年龄排序成功");
}
//动态版本
void destroycontact(struct contact* pc)
{
free(pc->date);
pc->date = NULL;
pc->capacity = 0;
pc->sz = 0;
}
1.3.3存储数据版本
#define _CRT_SECURE_NO_WARNINGS 1
#include"contact.h"
int checkcapacity(struct contact* pc);
void loadcontact(struct contact* pc)
{
//打开文件
FILE* pfr = fopen("date.txt", "rb");
if (NULL == pfr)
{
perror("fopen");
return ;
}
//读文件
struct peoinfo tmp = { 0 };
while (fread(&tmp, sizeof(struct peoinfo), 1, pfr))
{
//考虑增容
checkcapacity(pc);
pc->date[pc->sz] = tmp;
pc->sz++;
}
fclose(pfr);
pfr = NULL;
}
//静态初始化
//void intcontact(struct contact *pc)
//{
// assert(pc);
// pc->sz = 0;
// memset(pc->date, 0, 100 * sizeof(struct peoinfo));
//}
//动态版本
void intcontact(struct contact* pc)
{
assert(pc);
pc->date = (struct peoinfo*)malloc(CAPACITY_SZ * sizeof(struct peoinfo));
if (pc->date == NULL)
{
perror("intcontact()");
}
pc->sz = 0;
pc->capacity = CAPACITY_SZ;
loadcontact(pc);
}
//静态版本
//void addcontact(struct contact* pc)
//{
// assert(pc);
// if (pc->sz == 100)
// {
// printf("通讯录已满,无法添加\n");
// return;
// }
// printf("请输入名字");
// scanf("%s", pc->date[pc->sz].name);
// printf("请输入性别");
// scanf("%s", pc->date[pc->sz].sex);
// printf("请输入年龄");
// scanf("%d", &(pc->date[pc->sz].age));
// printf("请输入电话");
// scanf("%s", pc->date[pc->sz].tele);
// printf("请输入地址");
// scanf("%s", pc->date[pc->sz].addr);
// pc->sz++;
// printf("成功添加联系人\n");
//}
//动态版本
int checkcapacity(struct contact* pc)
{
if (pc->sz == pc->capacity)
{
struct peoinfo* ptr = (struct peoinfo*)realloc(pc->date, (pc->capacity + sc) * sizeof(struct peoinfo));
if (ptr != NULL)
{
pc->date = ptr;
pc->capacity += sc;
printf("增容成功\n");
return 1;
}
else
{
perror("addcontact()");
return 0;
}
}
else
return 1;
}
void addcontact(struct contact* pc)
{
assert(pc);
if (0 == checkcapacity(pc))
{
return;
}
printf("请输入名字");
scanf("%s", pc->date[pc->sz].name);
printf("请输入性别");
scanf("%s", pc->date[pc->sz].sex);
printf("请输入年龄");
scanf("%d", &(pc->date[pc->sz].age));
printf("请输入电话");
scanf("%s", pc->date[pc->sz].tele);
printf("请输入地址");
scanf("%s", pc->date[pc->sz].addr);
pc->sz++;
printf("成功添加联系人\n");
}
void showcontact(const struct contact* pc)
{
int i = 0;
printf("%20s\t%5s\t%5s\t%12s\t%30s\n","姓名","性别","年龄","电话","地址");
for (i = 0; i < pc->sz; i++)
printf("%20s\t%5s\t%5d\t%12s\t%30s\n", pc->date[i].name,
pc->date[i].sex,
pc->date[i].age,
pc->date[i].tele,
pc->date[i].addr);
}
static int find_name(const struct contact* pc,char name[])
{
int i = 0;
for (i = 0; i < pc->sz; i++)
{
if (0 == strcmp(pc->date[i].name, name))
{
return i;
}
}
return -1;
}
void delcontact(struct contact* pc)
{
char name[maxname];
printf("请输入要删除人的名字");
scanf("%s", name);
int ret=find_name(pc, name);
if (ret == -1)
printf("要删除的人不存在\n");
else
{
int j = 0;
for (j = ret; j < pc->sz-1; j++)
{
pc->date[j] = pc->date[j + 1];
}
pc->sz--;
printf("成功删除指定联系人\n");
}
}
void searchcontact(const struct contact*pc)
{
char name[maxname];
printf("请输入要查找人的名字");
scanf("%s", name);
int ret = find_name(pc, name);
if (ret == -1)
printf("要查找的人不存在\n");
else
{
printf("%20s\t%5s\t%5s\t%12s\t%30s\n", "姓名", "性别", "年龄", "电话", "地址");
printf("%20s\t%5s\t%5d\t%12s\t%30s\n", pc->date[ret].name,
pc->date[ret].sex,
pc->date[ret].age,
pc->date[ret].tele,
pc->date[ret].addr);
}
}
void modifycontact(struct contact* pc)
{
char name[maxname];
printf("请输入要修改人的名字");
scanf("%s", name);
int ret = find_name(pc, name);
if (ret == -1)
printf("要查找的人不存在\n");
else
{
printf("请输入名字");
scanf("%s", pc->date[ret].name);
printf("请输入性别");
scanf("%s", pc->date[ret].sex);
printf("请输入年龄");
scanf("%d", &(pc->date[ret].age));
printf("请输入电话");
scanf("%s", pc->date[ret].tele);
printf("请输入地址");
scanf("%s", pc->date[ret].addr);
printf("修改成功\n");
}
}
int cmpage(const void* e1, const void* e2)
{
return((struct peoinfo*)e1)->age - ((struct peoinfo*)e2)->age;
}
void sortcontact(struct contact* pc)
{
qsort(pc->date, pc->sz, sizeof(struct peoinfo), cmpage);
printf("按年龄排序成功");
}
//动态版本
void destroycontact(struct contact* pc)
{
free(pc->date);
pc->date = NULL;
pc->capacity = 0;
pc->sz = 0;
}void savecontact(struct contact* pc)
{
//打开文件
FILE*pfw=fopen("date.txt","wb");
if (NULL == pfw)
{
perror("fopen");
return 1 ;
}
int i = 0;
for (i = 0; i < pc->sz; i++)
{
fwrite(pc->date+i, sizeof(struct peoinfo), 1, pfw);
}
//关闭文件
fclose(pfw);
pfw = NULL;
}
总结
对于枚举结构体函数部分的应用,会后期优化