C语言实战小项目——通讯录1.0—— 博客入口
本次优化版本与上一次的1.0版本相比,改变了原有的固定内存存储通讯录联系人的方式。
原来的存储联系人方式是我们规定一个数组存储1000个结构体进行存储联系人的各种信息,但是有时候我们用不了这么多的空间,没有那么多的联系人,那样我们开辟的内存空间就浪费了,所以这次我们的通讯录做了以下优化:
1. 通讯录我们开辟的动态内存空间默认最大的联系人数量是2个
2. 如果再添加联系人,我们将调整动态内存空间的大小,再次增加两个联系人的数量,这样极大的节约了空间的占有率。
3. 我们开辟的动态内存需要free ,防止内存泄漏的问题,所以在EXIT的功能后添加了DestroyContact函数来对开辟的空间进行释放。
0.退出菜单
1.添加联系人信息
2.删除指定名字的联系人信息
3.修改联系人的信息
4.查找好友的信息
5.展示通讯录联系人信息
我们根据通讯录的各项功能进行编写页面菜单
void menu()
{
//打印通讯录菜单
//0.退出菜单
//1.添加联系人信息
//2.删除指定名字的联系人信息
//3.修改联系人的信息
//4.查找好友的信息
//5.展示通讯录联系人信息
//6.对通讯录指定信息进行排序
printf("*************************************************\n");
printf("********** ——欢迎来到通讯录菜单—— *********\n");
printf("********** 0.退出菜单 *********\n");
printf("********** 1.添加联系人信息 *********\n");
printf("********* 2.删除联系人信息 *********\n");
printf("********* 3.修改联系人信息 *********\n");
printf("********* 4.查找联系人信息 *********\n");
printf("********* 5.展示联系人信息 *********\n");
printf("*************************************************\n");
}
//将菜单的功能一一列举出来,以枚举的类型呈现
enum
{
EXIT,
ADD,
DEL,
MODIFY,
SEARCH,
SHOW,
};
int main()
{
int input = 0;
//创建通讯录
struct Contact con; //Con就是通讯录,里面包含1000个人的信息,及size
InitContact(&con);
do
{
menu();
printf("请选择功能:>");
scanf("%d", &input);
switch (input)
{
case ADD:
AddContact(&con);
break;
case DEL:
DelContact(&con);
break;
case MODIFY :
MotifyContact(&con);
break;
case SEARCH :
SearchContact(&con);
break;
case SHOW:
ShowContact(con);
break;
case EXIT:
DestroyContact(&con);
break;
default:
printf("选择错误,请重新输入!!\n");
break;
}
} while(input);
return 0;
}
#define _CRT_SECURE_NO_WARNINGS 1
#define MAX 1000
#define MAX_name 20
#define MAX_tel 20
#define MAX_sex 5
#define MAX_addr 30
#define DEFAULT_SZ 2
struct PeoInfor
{
char name[MAX_name];
int age;
char sex[MAX_sex];
char tel[MAX_tel];
char addr[MAX_addr];
};
//struct Contact
//{
// struct PeoInfor date[MAX]; // 存放个人信息
// int size; //记录当前已有的元素个数
//};
//通讯录信息的动态内存的建立
struct Contact
{
struct PeoInfor* date; // 存放个人信息
int size; //表示当前通讯录的联系人的数量
int capacity; //表示当天通讯录的联系人的最大空间能容纳的联系人数量
};
//动态内存的初始化
void InitContact(struct Contact * ps)
{
ps->date = (struct PeoInfor *)malloc(DEFAULT_SZ * sizeof(struct PeoInfor));
if (ps->date == NULL)
{
printf("通讯录初始化失败");
exit(1);
}
ps->size = 0;
ps->capacity = 2;
}
void AddContact(struct Contact* ps)
{
if (ps->size == ps->capacity)
{
//增容
struct PeoInfor * ptr = realloc(ps->date, (ps->capacity + 2)*sizeof(struct PeoInfor));
if (ptr == NULL)
{
printf("增容失败\n");
return;
}
else
{
printf("增容成功\n");
ps->capacity += 2;
}
}
printf("请输入姓名:>");
scanf("%s", ps->date[ps->size].name);
printf("请输入年龄:>");
scanf("%d", &(ps->date[ps->size].age));
printf("请输入性别:>");
scanf("%s", ps->date[ps->size].sex);
printf("请输入电话:>");
scanf("%s", ps->date[ps->size].tel);
printf("请输入地址:>");
scanf("%s", ps->date[ps->size].addr);
ps->size++;
printf("添加成功\n");
}
void DelContact(struct Contact *ps)
{
// 查找要删除的人在什么位置,根据名字
char name[MAX_name];
printf("请输入要删除的联系人名字:>");
scanf("%s", name);
int i = 0;
int j = 0;
//查找名字
for (i = 0; i < ps->size; i++)
{
if (0 == strcmp(name, ps->date[j].name))
{
break;
}
}
if (i==ps->size) // i从循环里出来,strcmp还是不等于0
{
printf("未找到该联系人的信息\n");
}
else
{
for (j = i; j < ps->size; j++)
{
ps->date[j] = ps->date[j + 1];
}
}
ps->size--;
printf("删除成功\n");
}
void MotifyContact(struct Contact *ps)
{
char name[MAX_name];
printf("请输入要删除的联系人名字:>");
scanf("%s", name);
int i = 0;
//查找名字
for (i = 0; i < ps->size; i++)
{
if (0 == strcmp(name, ps->date[i].name))
{
break;
}
}
if (i == ps->size) // i从循环里出来,strcmp还是不等于0
{
printf("未找到该联系人的信息\n");
}
//表示找到该联系人
//对下标为i的联系人信息进行修改
else
{
printf("请输入姓名:>");
scanf("%s", ps->date[i].name);
printf("请输入年龄:>");
scanf("%d", &(ps->date[i].age));
printf("请输入性别:>");
scanf("%s", ps->date[i].sex);
printf("请输入电话:>");
scanf("%s", ps->date[i].tel);
printf("请输入地址:>");
scanf("%s", ps->date[i].addr);
}
printf("修改成功\n");
}
void SearchContact(struct Contact *ps)
{
char name[MAX_name];
printf("请输入要查找的联系人名字:>");
scanf("%s", name);
int i = 0;
//查找名字
for (i = 0; i < ps->size; i++)
{
if (0 == strcmp(name, ps->date[i].name))
{
break;
}
}
if (i == ps->size) // i从循环里出来,strcmp还是不等于0
{
printf("未找到该联系人的信息\n");
}
//表示找到该联系人
//对下标为i的联系人信息进行显示
else
{
printf("%10s\t%4s\t%5s\t%12s\t%20s\n", "名字", "年龄", "性别", "电话", "地址");
printf("%10s\t%4d\t%5s\t%12s\t%20s\n",
ps->date[i].name,
ps->date[i].age,
ps->date[i].sex,
ps->date[i].tel,
ps->date[i].addr);
}
}
void ShowContact(struct Contact ps)
{
if (ps.size == 0)
{
printf("通讯录为空,无法展示\n");
}
else
{
printf("%10s\t%4s\t%5s\t%12s\t%20s\n","名字","年龄","性别","电话","地址");
int i = 0;
for (i = 0; i < ps.size; i++)
{
printf("%10s\t%4d\t%5s\t%12s\t%20s\n",
ps.date[i].name,
ps.date[i].age,
ps.date[i].sex,
ps.date[i].tel,
ps.date[i].addr);
}
}
}
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include "contact.h"
#include
void menu()
{
//打印通讯录菜单
//0.退出菜单
//1.添加联系人信息
//2.删除指定名字的联系人信息
//3.修改联系人的信息
//4.查找好友的信息
//5.展示通讯录联系人信息
//6.对通讯录指定信息进行排序
printf("*************************************************\n");
printf("********** ——欢迎来到通讯录菜单—— *********\n");
printf("********** 0.退出菜单 *********\n");
printf("********** 1.添加联系人信息 *********\n");
printf("********* 2.删除联系人信息 *********\n");
printf("********* 3.修改联系人信息 *********\n");
printf("********* 4.查找联系人信息 *********\n");
printf("********* 5.展示联系人信息 *********\n");
printf("*************************************************\n");
}
//将菜单的功能一一列举出来,以枚举的类型呈现
enum
{
EXIT,
ADD,
DEL,
MODIFY,
SEARCH,
SHOW,
};
int main()
{
int input = 0;
//创建通讯录
struct Contact con; //Con就是通讯录,里面包含1000个人的信息,及size
InitContact(&con);
do
{
menu();
printf("请选择功能:>");
scanf("%d", &input);
switch (input)
{
case ADD:
AddContact(&con);
break;
case DEL:
DelContact(&con);
break;
case MODIFY :
MotifyContact(&con);
break;
case SEARCH :
SearchContact(&con);
break;
case SHOW:
ShowContact(con);
break;
case EXIT:
DestroyContact(&con);
break;
default:
printf("选择错误,请重新输入!!\n");
break;
}
} while(input);
return 0;
}
#define _CRT_SECURE_NO_WARNINGS 1
#include
#include
#include "contact.h"
#include
//静态通讯录的信息初始化
//void InitContact(struct Contact* ps)
//{
// memset(ps->date, 0, sizeof(ps->date));
// ps->size = 0; //设置通讯录的元素有0个
//}
//动态通讯录的信息初始化
void InitContact(struct Contact * ps)
{
ps->date = (struct PeoInfor *)malloc(DEFAULT_SZ * sizeof(struct PeoInfor));
if (ps->date == NULL)
{
printf("通讯录初始化失败");
exit(1);
}
ps->size = 0;
ps->capacity = 2;
}
//静态内存增添联系人的信息
//void AddContact(struct Contact* ps)
//{
// if (ps->size == MAX)
// {
// printf("该通讯录空间已满,无法储存\n");
// }
// else
// {
// printf("请输入姓名:>");
// scanf("%s", ps->date[ps->size].name);
// printf("请输入年龄:>");
// scanf("%d", &(ps->date[ps->size].age));
// printf("请输入性别:>");
// scanf("%s", ps->date[ps->size].sex);
// printf("请输入电话:>");
// scanf("%s", ps->date[ps->size].tel );
// printf("请输入地址:>");
// scanf("%s", ps->date[ps->size].addr);
// ps->size++;
// printf("添加成功\n");
// }
//
//}
//动态内存实现增添联系人的信息
void AddContact(struct Contact* ps)
{
if (ps->size == ps->capacity)
{
//增容
struct PeoInfor * ptr = realloc(ps->date, (ps->capacity + 2)*sizeof(struct PeoInfor));
if (ptr == NULL)
{
printf("增容失败\n");
return;
}
else
{
printf("增容成功\n");
//如果增容成功,那么ptr的值要赋给 ps->date;
// ptr是realloc 开辟的内存,可能返回原来ps->date的地址,也可能是一个新的内存空间的地址
ps->date = ptr;
ps->capacity += 2;
}
}
printf("请输入姓名:>");
scanf("%s", ps->date[ps->size].name);
printf("请输入年龄:>");
scanf("%d", &(ps->date[ps->size].age));
printf("请输入性别:>");
scanf("%s", ps->date[ps->size].sex);
printf("请输入电话:>");
scanf("%s", ps->date[ps->size].tel);
printf("请输入地址:>");
scanf("%s", ps->date[ps->size].addr);
ps->size++;
printf("添加成功\n");
}
void ShowContact(struct Contact ps)
{
if (ps.size == 0)
{
printf("通讯录为空,无法展示\n");
}
else
{
printf("%10s\t%4s\t%5s\t%12s\t%20s\n","名字","年龄","性别","电话","地址");
int i = 0;
for (i = 0; i < ps.size; i++)
{
printf("%10s\t%4d\t%5s\t%12s\t%20s\n",
ps.date[i].name,
ps.date[i].age,
ps.date[i].sex,
ps.date[i].tel,
ps.date[i].addr);
}
}
}
void DelContact(struct Contact *ps)
{
// 查找要删除的人在什么位置,根据名字
char name[MAX_name];
printf("请输入要删除的联系人名字:>");
scanf("%s", name);
int i = 0;
int j = 0;
//查找名字
for (i = 0; i < ps->size; i++)
{
if (0 == strcmp(name, ps->date[j].name))
{
break;
}
}
if (i==ps->size) // i从循环里出来,strcmp还是不等于0
{
printf("未找到该联系人的信息\n");
}
else
{
for (j = i; j < ps->size; j++)
{
ps->date[j] = ps->date[j + 1];
}
}
ps->size--;
printf("删除成功\n");
}
void MotifyContact(struct Contact *ps)
{
char name[MAX_name];
printf("请输入要删除的联系人名字:>");
scanf("%s", name);
int i = 0;
//查找名字
for (i = 0; i < ps->size; i++)
{
if (0 == strcmp(name, ps->date[i].name))
{
break;
}
}
if (i == ps->size) // i从循环里出来,strcmp还是不等于0
{
printf("未找到该联系人的信息\n");
}
//表示找到该联系人
//对下标为i的联系人信息进行修改
else
{
printf("请输入姓名:>");
scanf("%s", ps->date[i].name);
printf("请输入年龄:>");
scanf("%d", &(ps->date[i].age));
printf("请输入性别:>");
scanf("%s", ps->date[i].sex);
printf("请输入电话:>");
scanf("%s", ps->date[i].tel);
printf("请输入地址:>");
scanf("%s", ps->date[i].addr);
}
printf("修改成功\n");
}
void SearchContact(struct Contact *ps)
{
char name[MAX_name];
printf("请输入要查找的联系人名字:>");
scanf("%s", name);
int i = 0;
//查找名字
for (i = 0; i < ps->size; i++)
{
if (0 == strcmp(name, ps->date[i].name))
{
break;
}
}
if (i == ps->size) // i从循环里出来,strcmp还是不等于0
{
printf("未找到该联系人的信息\n");
}
//表示找到该联系人
//对下标为i的联系人信息进行显示
else
{
printf("%10s\t%4s\t%5s\t%12s\t%20s\n", "名字", "年龄", "性别", "电话", "地址");
printf("%10s\t%4d\t%5s\t%12s\t%20s\n",
ps->date[i].name,
ps->date[i].age,
ps->date[i].sex,
ps->date[i].tel,
ps->date[i].addr);
}
}
//对开辟的动态内存空间进行释放,防止内存泄漏
void DestroyContact(struct Contact *ps)
{
free(ps->date);
ps->date = NULL;
ps->size = 0;
ps->capacity = 0;
}
#define _CRT_SECURE_NO_WARNINGS 1
#define MAX 1000
#define MAX_name 20
#define MAX_tel 20
#define MAX_sex 5
#define MAX_addr 30
#define DEFAULT_SZ 2 //通讯录系统默认的内存存储的联系人数量
struct PeoInfor
{
char name[MAX_name];
int age;
char sex[MAX_sex];
char tel[MAX_tel];
char addr[MAX_addr];
};
//静态通讯录的结构体创建
//struct Contact
//{
// struct PeoInfor date[MAX]; // 存放个人信息
// int size; //记录当前已有的元素个数
//};
//动态通讯录的结构体创建
struct Contact
{
struct PeoInfor* date; // 存放个人信息
int size; //表示当前通讯录的联系人的数量
int capacity;
};
// 声明函数
void InitContact(struct Contact* ps); //通讯录信息初始化
void AddContact(struct Contact* ps); //增加联系人相关信息
void ShowContact(struct Contact ps); //展示联系人相关信息
void DelContact(struct Contact *ps); //删除联系人相关信息
void MotifyContact(struct Contact *ps); //修改联系人相关信息
void SearchContact(struct Contact *ps); //搜索联系人相关信息
void DestroyContact(struct Contact *ps); //程序结束后释放开辟的动态内存,防止内存泄漏
我们写的通讯录实现了动态内存空间管理的功能,我们可以在这个程序内进行以上增删改查功能,但是我们退出了这个程序以后,我们存储的联系人信息将全部丢失,无法保存在一个固定的文件里,所以仍然存在限制和缺点。
这就是通讯录的2.0版本,后续将持续更新,我们将在3.0版本升级为拥有文件操作保存联系人信息的通讯录。
欢迎大家的关注与欣赏!!
C语言实战项目——通讯录3.0已更新