🎈🎈 作者 whispar
🎈🎈专栏 : C语言从无到有
✨放低姿态,空杯心态✨
目录
🌊test.c
✅使用枚举类型,使得菜单部分的代码可读性更强,便于理解
- #define _CRT_SECURE_NO_WARNINGS
-
- #include"contact.h"
- enum Option
- {
- EXIT,
- ADD,
- DEL,
- SEARCH,
- MODIFY,
- SHOW,
- SORT
- };
- void menu() {
- printf("*******\ 1.add 2.del /*******\n");
- printf("*******\ 3.search 4.modify /*******\n");
- printf("*******\ 5.show 6.sort /*******\n");
- }
- int main(){
- 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);
-
- return 0;
- }
-
🌊contact.c
✅在contact.c中静态的版本无法满足我们的需求,因此我们在动态的版本当中使用realloc函数就可以做到对动态开辟内存大小,我们可以封装一个函数来判断容量是否足够,不够的话进行扩容。
✅在contact.c中文件的版本可以将创建的数据存储在本地,当程序退出时,数据依然存在,使用文件我们可以将数据直接存放在电脑的硬盘上,做到了数据的持久化。
- #define _CRT_SECURE_NO_WARNINGS 1
-
- #include "contact.h"
-
- //静态的版本
- //void InitContact(Contact* pc)
- //{
- // assert(pc);
- // pc->count = 0;
- // memset(pc->data, 0, sizeof(pc->data));
- //}
-
-
- void CheckCapacity(Contact* pc)
- {
- if (pc->count == pc->capacity)
- {
- PeoInfo* ptr = (PeoInfo*)realloc(pc->data, (pc->capacity + INC_SZ) * sizeof(PeoInfo));
- if (ptr == NULL)
- {
- printf("AddContact::%s\n", strerror(errno));
- return;
- }
- else
- {
- pc->data = ptr;
- pc->capacity += INC_SZ;
- printf("增容成功\n");
- }
- }
- }
-
- void LoadContact(Contact* pc)
- {
- FILE* pfRead = fopen("contact.txt", "rb");
- if (pfRead == NULL)
- {
- perror("LoadContact");
- return;
- }
- PeoInfo tmp = { 0 };
-
- while (fread(&tmp, sizeof(PeoInfo), 1, pfRead) == 1)
- {
- CheckCapacity(pc);
-
- pc->data[pc->count] = tmp;
- pc->count++;
- }
-
- fclose(pfRead);
- pfRead = NULL;
- }
-
- //动态的版本
- int InitContact(Contact* pc)
- {
- assert(pc);
- pc->count = 0;
- pc->data = (PeoInfo*)calloc(DEFAULT_SZ, sizeof(PeoInfo));
- if (pc->data == NULL)
- {
- printf("InitContact::%s\n", strerror(errno));
- return 1;
- }
- pc->capacity = DEFAULT_SZ;
- //加载文件的信息到通讯录中
- LoadContact(pc);
- return 0;
- }
-
- void DestroyContact(Contact* pc)
- {
- assert(pc);
- free(pc->data);
- pc->data = NULL;
- }
-
- //静态的版本
- //void AddContact(Contact* pc)
- //{
- // assert(pc);
- // if (pc->count == MAX)
- // {
- // printf("通讯录已满,无法添加\n");
- // return;
- // }
- // //
- // printf("请输入名字:>");
- // scanf("%s", pc->data[pc->count].name);
- // printf("请输入年龄:>");
- // scanf("%d", &(pc->data[pc->count].age));
- // printf("请输入性别:>");
- // scanf("%s", pc->data[pc->count].sex);
- // printf("请输入电话:>");
- // scanf("%s", pc->data[pc->count].tele);
- // printf("请输入地址:>");
- // scanf("%s", pc->data[pc->count].addr);
- //
- // pc->count++;
- // printf("增加成功\n");
- //}
-
-
-
- //动态的版本
- void AddContact(Contact* pc)
- {
- assert(pc);
- //增容
- CheckCapacity(pc);
- //
- printf("请输入名字:>");
- scanf("%s", pc->data[pc->count].name);
- printf("请输入年龄:>");
- scanf("%d", &(pc->data[pc->count].age));
- printf("请输入性别:>");
- scanf("%s", pc->data[pc->count].sex);
- printf("请输入电话:>");
- scanf("%s", pc->data[pc->count].tele);
- printf("请输入地址:>");
- scanf("%s", pc->data[pc->count].addr);
-
- pc->count++;
- printf("增加成功\n");
- }
-
- void ShowContact(const Contact* pc)
- {
- assert(pc);
- int i = 0;
- printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址");
- for (i = 0; i < pc->count; i++)
- {
- printf("%-20s\t%-5d\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(Contact* pc, char name[])
- {
- assert(pc);
- int i = 0;
- for (i = 0; i < pc->count; i++)
- {
- if (0 == strcmp(pc->data[i].name, name))
- {
- return i;
- }
- }
-
- return -1;
- }
-
- void DelContact(Contact* pc)
- {
- char name[MAX_NAME] = { 0 };
- assert(pc);
- int i = 0;
- if (pc->count == 0)
- {
- printf("通讯录为空,没有信息可以删除\n");
- return;
- }
- printf("请输入要删除人的名字:>");
- scanf("%s", name);
- //删除
- //1. 查找
- int pos = FindByName(pc, name);
- if (pos == -1)
- {
- printf("要删除的人不存在\n");
- return;
- }
- //2. 删除
- for (i = pos; i < pc->count - 1; i++)
- {
- pc->data[i] = pc->data[i + 1];
- }
- pc->count--;
-
- printf("删除成功\n");
- }
-
- void SearchContact(Contact* pc)
- {
- assert(pc);
- char name[MAX_NAME] = { 0 };
- printf("请输入要查找人的名字:>");
- scanf("%s", name);
- //1. 查找
- int pos = FindByName(pc, name);
- if (pos == -1)
- {
- printf("要查找的人不存在\n");
- return;
- }
- //2. 打印
- printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址");
- printf("%-20s\t%-5d\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);
- //1. 查找
- int pos = FindByName(pc, name);
- if (pos == -1)
- {
- printf("要修改的人不存在\n");
- return;
- }
- printf("要修改的人的信息已经查找到,接下来开始修改\n");
- //2. 修改
- 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");
- }
-
-
- int cmp_peo_by_name(const void* e1, const void* e2)
- {
- return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
- }
-
- //按照名字来排序
- void SortContact(Contact* pc)
- {
- assert(pc);
- qsort(pc->data, pc->count, sizeof(PeoInfo), cmp_peo_by_name);
- printf("排序成功\n");
- }
-
- void SaveContact(const Contact* pc)
- {
- assert(pc);
- FILE* pfWrite = fopen("contact.txt", "wb");
- if (pfWrite == NULL)
- {
- perror("SaveContact");
- return;
- }
- //写文件-二进制的形式
- int i = 0;
- for (i = 0; i < pc->count; i++)
- {
- fwrite(pc->data + i, sizeof(PeoInfo), 1, pfWrite);
- }
-
- fclose(pfWrite);
- pfWrite = NULL;
- }
-
-
🌊contact.h
- #pragma once
-
- #include
- #include
- #include
- #include
-
- #define DEFAULT_SZ 3
- #define INC_SZ 2
-
- #define MAX 100
- #define MAX_NAME 20
- #define MAX_SEX 10
- #define MAX_TELE 12
- #define MAX_ADDR 30
-
- //类型的声明
- //
- //人的信息
- 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 count;//记录当前通讯录中实际人的个数
- //}Contact;
-
- //动态的版本
- typedef struct Contact
- {
- PeoInfo* data;//存放人的信息
- int count;//记录当前通讯录中实际人的个数
- int capacity;//当前通讯录的容量
- }Contact;
-
-
- //初始化通讯录
- int InitContact(Contact* pc);
-
- //销毁通讯录
- void DestroyContact(Contact* pc);
-
- //增加联系人都通讯录
- void AddContact(Contact* pc);
-
- //打印通讯中的信息
- void ShowContact(const Contact* pc);
-
- //删除指定联系人
- void DelContact(Contact* pc);
-
- //查找指定联系人
- void SearchContact(Contact* pc);
-
- //修改指定联系人
- void ModifyContact(Contact* pc);
-
- //排序通讯录中内容
- //按照名字来排序
- //按照年龄来排序
- //...
- void SortContact(Contact* pc);
-
- //保存通讯录的信息到文件
- void SaveContact(const Contact* pc);
-
- //加载文件的信息到通讯录
- void LoadContact(Contact* pc);
-
✅静态版本基本功能的实现
✅动态版本扩容功能的实现
✅文件版本保存本地功能实现
💖如果文章对你有帮助,请多多点赞、收藏、评论、关注支持!!💖