搜索品牌价值的网站,本科学历提升,源码网棋牌,国外免费wordpress主题 作者简介#xff1a;დ旧言~#xff0c;目前大一#xff0c;现在学习Java#xff0c;c#xff0c;c#xff0c;Python等 座右铭#xff1a;松树千年终是朽#xff0c;槿花一日自为荣。 望小伙伴们点赞#x1f44d;收藏✨加关注哟#x1f495;#x1… 作者简介დ旧言~目前大一现在学习JavaccPython等 座右铭松树千年终是朽槿花一日自为荣。 望小伙伴们点赞收藏✨加关注哟 前言 当我们需要办一些业务时需要录入我们的个人信息我们的个人信息放在一个系统中我们简称这个系统为通讯录而这个通讯录可以存储我们的名字性别电话地址....等等等。今天我们实现一个简单的通讯录。 主体
咱们需要建立一个项目项目里面有test.cContact.hContact.c。 其实这里contact.c是重点咱们一个一个文件看看它们是如何实现的。 contact.h的实现
这个文件用来声明的其中包括函数声明包含头文件实现动态通讯录枚举的实现定义元素类型。咱们逐个实现。
定义枚举和元素类型
定义枚举是为了方便使用switch枚举第一个元素以0为起始位置。
//定义枚举,方便使用switch改变
enum OPTION
{EXIT,//0ADD,//1DEL,//2SEARCH,//3MODIFY,//4SHOW,//5SORT//6
};
通讯录需要存入的数据有名字性别电话地址因此来定义类型。
//宏定义
#define MAX 100//为静态通讯录服务
#define MAX_NAME 20//名字的最大值
#define MAX_SEX 5//性别的最大值
#define MAX_TELE 12//电话的最大值
#define MAX_ADDR 30//地址的最大值#define DEFAULT_SZ 3//开始通讯录空间大小
#define INC_SZ 2//开辟空间数值大小//定义通讯录所包含的元素类型
typedef struct PeoInfo
{char name[MAX_NAME];int age;char sex[MAX_SEX];char tele[MAX_TELE];char addr[MAX_ADDR];
}PeoInfo; 这里用typedef来给结构体重新定义名字。
动态通讯录
正常我们写入的代码是这样的
//静态通讯录
//typedef struct Contact
//{
// PeoInfo data[MAX];
// int sz;
//}Contact;
这样就把通讯录写死了当通讯录的空间不够时无法实现扩容因此我们需要一个动态的通讯录而动态的通讯录有什么呢 1.存放数据的空间这里需要结构体指针才能指向下一个元素这里在动态内存管理已经讲解过了哟 2.当前放的有效元素的个数 3.通讯录当前的最大容量 //动态通讯录
typedef struct Contact
{PeoInfo* data;//指向了存放数据的空间int sz;//记录的当前放的有效元素的个数int capacity;//通讯录当前的最大容量
}Contact;
函数声明
这里就直接上代码了具体内容咱们到contact.c里面讲解
//函数声明//初始化通讯录
void InitContact(Contact* pc);//增加联系人
void AddContact(Contact* pc);//显示所有联系人的信息
void ShowContact(const Contact* pc);//删除指定联系人
void DelContact(Contact* pc);//查找指定联系人
void SearchContact(const Contact* pc);//修改指定联系人
void ModifyContact(Contact* pc);//销毁通讯录
void DestroyContact(Contact* pc);//保存通讯录信息到文件
void SaveContact(Contact* pc);//排序
void SortContact(Contact* pc) test.c的实现 这里的内容和博主写的三子棋与扫雷极其相似首先打印菜单其次能实现循环进行多次玩最后根据自己选定内容进行不同的程序。 1.首先需要包含头文件包含#includecontact.h 2.其次写上简单的void menu()实现打印菜单 3.然后写上void test()来实现通讯录的各种功能 4.最后写上主函数 #includecontact.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);
}void test()
{//定义变量来实现输入int input 0;//创建结构体Contact con;//初始化通讯录InitContact(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://排序//按照名字排序//按照年龄排序break;case EXIT:SaveContact(con);DestroyContact(con);printf(退出通讯录\n);break;default:printf(选择错误, 重新选择\n);break;}} while (input);
}//主函数
int main()
{//调用函数test();return 0;
} contact.c的实现重点 其实contact.c是通讯录的核心也是通讯录最难的部分咱们把这部分分成一块一块一起来学习这部分。
初始化讯录 如果我们写上静态版本的通讯录就无法实现录入多个用户信息因此我们只能续写动态版本的通讯录。 1.需要为data指向了存放数据的空间开辟空间 2.判断data是否为空防止在增删查找本身为空 3.对sz记录的当前放的有效元素的个数和capacity通讯录当前的最大容量初始化 4.保存在文件调用函数后面会讲解 //静态版本
//void InitContact(Contact* pc)
//{
// assert(pc);
// memset(pc-data, 0, sizeof(pc-data));
// pc-sz 0;
//}//初始化通讯录(动态)
void InitContact(Contact* pc)
{//判断pc是否为空assert(pc);//开辟空间pc-data (PeoInfo*)malloc(sizeof(PeoInfo));//判断是否为空if (pc-data NULL){perror(InitContact);return 0;}//初始化pc-sz 0;pc-capacity DEFAULT_SZ;//文件中保存的信息加载到通讯录中LoadContact(pc);
} 保存文件
这里因为还没讲到文件管理大家就算看看啦。 void LoadContact(Contact* pc)
{//打开文件FILE* pf fopen(contact.dat, rb);if (pf NULL){perror(LoadContact);return;}//读文件PeoInfo tmp { 0 };while (fread(tmp, sizeof(PeoInfo), 1, pf)){//这里如果内存不足需要扩容if (0 CheckCapacity(pc))return;pc-data[pc-sz] tmp;pc-sz;}//关闭文件fclose(pf);pf NULL;
}//保存通讯录信息到文件
void SaveContact(Contact* pc)
{FILE* pf fopen(contact.dat, wb);if (pf NULL){perror(SaveContact);return;}//写数据int i 0;for (i 0; i pc-sz; i){fwrite(pc-data i, sizeof(PeoInfo), 1, pf);}//关闭文件fclose(pf);pf NULL;
} 扩容 当我们的内存不够时我们就需要括容。我们这里的sz记录的当前放的有效元素的个数等于capacity通讯录当前的最大容量时就需要扩容。这里我们用realloc来开辟空间做到对动态开辟内存大小的调整。 1.开辟空间采用结构体指针来接收开辟的空间。 2.判断是否开好相应的空间。 3.赋值 //是否需要扩容
int CheckCapacity(Contact* pc)
{//判断sz是否等于capacityif (pc-sz pc-capacity){//开辟空间PeoInfo* ptr (PeoInfo*)realloc(pc-data, (pc-capacity INC_SZ) * sizeof(PeoInfo));//判断if (ptr NULL){perror(CheckCapacity);return;}else{pc-data ptr;pc-capacity INC_SZ;printf(增容成功\n);return 1;}}
} 增加联系人 这个函数我们已经熟清熟路了这里我们只需注意sz记录的当前放的有效元素的个数需要因为需要指向下一个元素的位置。
//增加联系人
void AddContact(Contact* pc)
{//断言assert(pc);//如果通讯录为空直接跳出循环if (CheckCapacity(pc) 0){return;}//输入printf(请输入名字:);scanf(%s, pc-data[pc-sz].name);printf(请输入年龄:);scanf(%d, (pc-data[pc-sz].age));printf(请输入性别:);scanf(%s, pc-data[pc-sz].sex);printf(请输入电话:);scanf(%s, pc-data[pc-sz].tele);printf(请输入地址:);scanf(%s, pc-data[pc-sz].addr);//当空间不够时需要扩容CheckCapacity(pc);//指向下个元素pc-sz;printf(成功增加联系人\n);
} 显示所有联系人的信息
这里和打印没啥区别太简单了。
//显示所有联系人的信息
void ShowContact(const Contact* pc)
{//断言assert(pc);int i 0;//打印列标题printf(%-10s\t%-4s\t%-5s\t%-12s\t%-30s\n, 名字, 年龄, 性别, 电话, 地址);//打印数据for (i 0; i pc-sz; i){printf(%-10s\t%-4d\t%-5s\t%-12s\t%-30s\n,pc-data[i].name,pc-data[i].age,pc-data[i].sex,pc-data[i].tele,pc-data[i].addr);}
}
删除指定联系人 因为这里删除指定联系人和查找指定联系人都需要查找指定的人因此我们这里直接再写一个函数来遍历整个通讯录。 我们采用向前覆盖的方式来删除指定联系人。这里和数据结构的重合了大家有兴趣可以看看博主写的数据结构相关内容。 //查找元素下标
static int FindByName(const 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 };assert(pc);//删除printf(请输入要删除的人名字:);scanf(%s, name);//找到要删除的人int del FindByName(pc, name);if (del -1){printf(要删除的人不存在\n);return;}int i 0;//删除坐标位del的联系人向前覆盖for (i del; i pc-sz - 1; i){pc-data[i] pc-data[i 1];}//要向后退一个元素pc-sz--;printf(成功删除联系人\n);
} 注意需要让sz记录的当前放的有效元素的个数--.
查找指定联系人
有了删除指定联系人的函数实现这个函数太简单了。
//查找指定联系人
void SearchContact(const Contact* pc)
{//断言assert(pc);char name[MAX_NAME] { 0 };printf(请输入要查找人的名字:);scanf(%s, name);int pos FindByName(pc, name);if (pos -1)printf(要查找的人不存在\n);else{printf(%-10s\t%-4s\t%-5s\t%-12s\t%-30s\n, 名字, 年龄, 性别, 电话, 地址);//打印数据printf(%-10s\t%-4d\t%-5s\t%-12s\t%-30s\n,pc-data[pos].name,pc-data[pos].age,pc-data[pos].sex,pc-data[pos].tele,pc-data[pos].addr);}
}
修改指定联系人
有了删除指定联系人的函数实现这个函数太简单了。
//修改指定联系人
void ModifyContact(Contact* pc)
{//断言assert(pc);char name[MAX_NAME] { 0 };printf(请输入要修改人的名字:);scanf(%s, name);int pos FindByName(pc, name);if (pos -1)printf(要修改的人不存在\n);else{printf(请输入名字:);scanf(%s, pc-data[pos].name);printf(请输入年龄:);scanf(%d, (pc-data[pos].age));printf(请输入性别:);scanf(%s, pc-data[pos].sex);printf(请输入电话:);scanf(%s, pc-data[pos].tele);printf(请输入地址:);scanf(%s, pc-data[pos].addr);printf(修改成功\n);}
}
销毁通讯录
当我们不再使用通讯录了就要释放内存所有的元素置0。
//销毁通讯录
void DestroyContact(Contact* pc)
{//释放free(pc-data);//置为空和0pc-data NULL;pc-capacity 0;pc-sz 0;
} 排序 这里我们就不得不提快排了博主写过一篇关于快排的博客大家可以仔细阅读一下在这里我们就不再多多赘述了。
//排序
int cmp_s(const void* elem1, const void* elem2)
{return strcmp((char*)elem1, (char*)elem2);
}void SortContact(Contact* pc)
{qsort(pc, pc-sz, sizeof(pc-data[0]), cmp_s);printf(%-10s\t%-5s\t%-10s\t%-5s\t%-10s\n, 姓名, 年龄, 电话, 性别, 地址);for (int i 0; i pc-sz; i){printf(%-10s\t%-5d\t%-10s\t%-5s\t%-10s\n,pc-data[i].name,pc-data[i].age,pc-data[i].tele,pc-data[i].sex,pc-data[i].addr);}
} 整体代码 contact.h
#pragma once//包含头文件
#includestdio.h
#includestdlib.h
#includeassert.h
#includestring.h//宏定义
#define MAX 100//为静态通讯录服务
#define MAX_NAME 20//名字的最大值
#define MAX_SEX 5//性别的最大值
#define MAX_TELE 12//电话的最大值
#define MAX_ADDR 30//地址的最大值#define DEFAULT_SZ 3//开始通讯录空间大小
#define INC_SZ 2//开辟空间数值大小//定义枚举,方便使用switch改变
enum OPTION
{EXIT,//0ADD,//1DEL,//2SEARCH,//3MODIFY,//4SHOW,//5SORT//6
};//定义通讯录所包含的元素类型
typedef struct PeoInfo
{char name[MAX_NAME];int age;char sex[MAX_SEX];char tele[MAX_TELE];char addr[MAX_ADDR];
}PeoInfo;//静态通讯录
//typedef struct Contact
//{
// PeoInfo data[MAX];
// int sz;
//}Contact;//动态通讯录
typedef struct Contact
{PeoInfo* data;//指向了存放数据的空间int sz;//记录的当前放的有效元素的个数int capacity;//通讯录当前的最大容量
}Contact;//函数声明//初始化通讯录
void InitContact(Contact* pc);//增加联系人
void AddContact(Contact* pc);//显示所有联系人的信息
void ShowContact(const Contact* pc);//删除指定联系人
void DelContact(Contact* pc);//查找指定联系人
void SearchContact(const Contact* pc);//修改指定联系人
void ModifyContact(Contact* pc);//销毁通讯录
void DestroyContact(Contact* pc);//保存通讯录信息到文件
void SaveContact(Contact* pc);//排序
void SortContact(Contact* pc); test.c
#includecontact.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);
}void test()
{//定义变量来实现输入int input 0;//创建结构体Contact con;//初始化通讯录InitContact(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(退出通讯录\n);break;default:printf(选择错误, 重新选择\n);break;}} while (input);
}//主函数
int main()
{test();return 0;
} contact.c
#includecontact.h//静态版本
//void InitContact(Contact* pc)
//{
// assert(pc);
// memset(pc-data, 0, sizeof(pc-data));
// pc-sz 0;
//}//静态版本
//
//void AddContact(Contact* pc)
//{
// assert(pc);
// if (pc-sz MAX)
// {
// printf(通讯录已满无法添加\n);
// return;
// }
//
// printf(请输入名字:);
// scanf(%s, pc-data[pc-sz].name);
// printf(请输入年龄:);
// scanf(%d, (pc-data[pc-sz].age));
// printf(请输入性别:);
// scanf(%s, pc-data[pc-sz].sex);
// printf(请输入电话:);
// scanf(%s, pc-data[pc-sz].tele);
// printf(请输入地址:);
// scanf(%s, pc-data[pc-sz].addr);
//
// pc-sz;
// printf(成功增加联系人\n);
//}//是否需要扩容声明函数
int CheckCapacity(Contact* pc);void LoadContact(Contact* pc)
{//打开文件FILE* pf fopen(contact.dat, rb);if (pf NULL){perror(LoadContact);return;}//读文件PeoInfo tmp { 0 };while (fread(tmp, sizeof(PeoInfo), 1, pf)){if (0 CheckCapacity(pc))return;pc-data[pc-sz] tmp;pc-sz;}//关闭文件fclose(pf);pf NULL;
}//初始化通讯录(动态)
void InitContact(Contact* pc)
{//判断pc是否为空assert(pc);//开辟空间pc-data (PeoInfo*)malloc(sizeof(PeoInfo));//判断是否为空if (pc-data NULL){perror(InitContact);return 0;}//初始化pc-sz 0;pc-capacity DEFAULT_SZ;//文件中保存的信息加载到通讯录中LoadContact(pc);
}//是否需要扩容
int CheckCapacity(Contact* pc)
{//判断sz是否等于capacityif (pc-sz pc-capacity){//开辟空间PeoInfo* ptr (PeoInfo*)realloc(pc-data, (pc-capacity INC_SZ) * sizeof(PeoInfo));//判断if (ptr NULL){perror(CheckCapacity);return;}else{pc-data ptr;pc-capacity INC_SZ;printf(增容成功\n);return 1;}}
}//增加联系人
void AddContact(Contact* pc)
{//断言assert(pc);//如果通讯录为空直接跳出循环if (CheckCapacity(pc) 0){return;}//输入printf(请输入名字:);scanf(%s, pc-data[pc-sz].name);printf(请输入年龄:);scanf(%d, (pc-data[pc-sz].age));printf(请输入性别:);scanf(%s, pc-data[pc-sz].sex);printf(请输入电话:);scanf(%s, pc-data[pc-sz].tele);printf(请输入地址:);scanf(%s, pc-data[pc-sz].addr);//CheckCapacity(pc);//指向下个元素pc-sz;printf(成功增加联系人\n);
}//显示所有联系人的信息
void ShowContact(const Contact* pc)
{//断言assert(pc);int i 0;//打印列标题printf(%-10s\t%-4s\t%-5s\t%-12s\t%-30s\n, 名字, 年龄, 性别, 电话, 地址);//打印数据for (i 0; i pc-sz; i){printf(%-10s\t%-4d\t%-5s\t%-12s\t%-30s\n,pc-data[i].name,pc-data[i].age,pc-data[i].sex,pc-data[i].tele,pc-data[i].addr);}
}//查找元素下标
static int FindByName(const 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 };assert(pc);//删除printf(请输入要删除的人名字:);scanf(%s, name);//找到要删除的人int del FindByName(pc, name);if (del -1){printf(要删除的人不存在\n);return;}int i 0;//删除坐标位del的联系人向前覆盖for (i del; i pc-sz - 1; i){pc-data[i] pc-data[i 1];}//要向后退一个元素pc-sz--;printf(成功删除联系人\n);
}//查找指定联系人
void SearchContact(const Contact* pc)
{//断言assert(pc);char name[MAX_NAME] { 0 };printf(请输入要查找人的名字:);scanf(%s, name);int pos FindByName(pc, name);if (pos -1)printf(要查找的人不存在\n);else{printf(%-10s\t%-4s\t%-5s\t%-12s\t%-30s\n, 名字, 年龄, 性别, 电话, 地址);//打印数据printf(%-10s\t%-4d\t%-5s\t%-12s\t%-30s\n,pc-data[pos].name,pc-data[pos].age,pc-data[pos].sex,pc-data[pos].tele,pc-data[pos].addr);}
}//修改指定联系人
void ModifyContact(Contact* pc)
{//断言assert(pc);char name[MAX_NAME] { 0 };printf(请输入要修改人的名字:);scanf(%s, name);int pos FindByName(pc, name);if (pos -1)printf(要修改的人不存在\n);else{printf(请输入名字:);scanf(%s, pc-data[pos].name);printf(请输入年龄:);scanf(%d, (pc-data[pos].age));printf(请输入性别:);scanf(%s, pc-data[pos].sex);printf(请输入电话:);scanf(%s, pc-data[pos].tele);printf(请输入地址:);scanf(%s, pc-data[pos].addr);printf(修改成功\n);}
}//销毁通讯录
void DestroyContact(Contact* pc)
{//释放free(pc-data);//置为空和0pc-data NULL;pc-capacity 0;pc-sz 0;
}//保存通讯录信息到文件
void SaveContact(Contact* pc)
{FILE* pf fopen(contact.dat, wb);if (pf NULL){perror(SaveContact);return;}//写数据int i 0;for (i 0; i pc-sz; i){fwrite(pc-data i, sizeof(PeoInfo), 1, pf);}//关闭文件fclose(pf);pf NULL;
}//排序
int cmp_s(const void* elem1, const void* elem2)
{return strcmp((char*)elem1, (char*)elem2);
}void SortContact(Contact* pc)
{qsort(pc, pc-sz, sizeof(pc-data[0]), cmp_s);printf(%-10s\t%-5s\t%-10s\t%-5s\t%-10s\n, 姓名, 年龄, 电话, 性别, 地址);for (int i 0; i pc-sz; i){printf(%-10s\t%-5d\t%-10s\t%-5s\t%-10s\n,pc-data[i].name,pc-data[i].age,pc-data[i].tele,pc-data[i].sex,pc-data[i].addr);}
}
结束语
今天内容就到这里啦时间过得很快大家沉下心来好好学习会有一定的收获的大家多多坚持嘻嘻成功路上注定孤独因为坚持的人不多。那请大家举起自己的小说手给博主一键三连有你们的支持是我最大的动力回见。