企业电商网站模板,长春最新通告今天,wordpress瓶颈,国家企业信用网官网传送门#xff1a;C语言-第九章-加餐#xff1a;文件位置指示器与二进制读写
目录
第一节#xff1a;思路整理
第二节#xff1a;代码编写 2-1.通讯录初始化 2-2.功能选择 2-3.增加 和 扩容 2-4.查看 2-5.查找 2-6.删除 2-7.修改 2-8.退出
第三节#xff1a;测试
下期…传送门C语言-第九章-加餐文件位置指示器与二进制读写
目录
第一节思路整理
第二节代码编写 2-1.通讯录初始化 2-2.功能选择 2-3.增加 和 扩容 2-4.查看 2-5.查找 2-6.删除 2-7.修改 2-8.退出
第三节测试
下期预告: 第一节思路整理 创建三个文件main.c用来测试程序Function.c用来存放函数定义Address.h用来存放函数声明、全局变量和各种宏。 通讯录的需求是能够长久的存储信息这就需要用到文件操作每次运行通讯录程序时从文件读取数据每次关闭程序时就把数据重新写入到文件中。 存储数据的容器 可以定义一个结构体类型 PeopleInfo每有一个人就用这个类型存储它的所有信息再定义一个结构体类型 AddressBook它用来存储所有 PeopleInfo并且还有通讯录的容量和已存储数量便于管理。
Address.h
struct PeopleInfo // 一个人的信息
{char _name[20]; // 名字int _age; // 年龄char _number[20]; // 号码
};
struct AddressBook // 通讯录
{struct PeopleInfo* _PeoPle; // 所有人的信息int _capacity; // 通讯录的容量int _size; // 通讯录当前存储的数量
}addressBook; 其他问题我们在写代码的过程中一一呈现。
第二节代码编写 我们把通讯录的各种功能一一实现 2-1.通讯录初始化 通讯录初始化包括设定通讯录的初始容量、从文件获取信息
Address.h
#define DEL_CAPACITY 10 // 默认初始容量
Function.c
void AddressInit()
{FILE* pf fopen(.//AddressBook.txt,rb); // 二进制读方式打开if (pf NULL){perror(文件打开失败\n);return;}addressBook._capacity DEL_CAPACITY;addressBook._PeoPle (struct PeopleInfo*)malloc(addressBook._capacity*sizeof(struct PeopleInfo)); // 开辟空间if (addressBook._PeoPle NULL)return;addressBook._size 0;// 从文件中读取数据while (0 ! fread(addressBook._PeoPle addressBook._size, sizeof(struct PeopleInfo), 1, pf)){addressBook._size;if (addressBook._size addressBook._capacity)Expansion(); // 扩容函数之后实现}fclose(pf);
} 2-2.功能选择 通讯录初始化完成后就编写代码实现对各种功能的选择
Function.c
void printMenu()
{printf(***********************************************\n);printf(***************1.增加*****2.删除***************\n);printf(***************3.查找*****4.修改***************\n);printf(***************5.查看*****0.退出***************\n);printf(***********************************************\n);
}void Select()
{printMenu(); // 打印菜单int select;while (1){printf(请选择:);scanf(%d, select);switch (select){case 1:ADD(); // 增加break;case 2:DEL(); // 删除break;case 3:Find();// 查找break;case 4:MOD(); // 修改 break;case 5:DIS(); // 查看break;case 0:EXIT();// 退出return 0;default:printf(非法的请求请重新输入:);}}
} switch 中的函数在之后一一实现。 2-3.增加 和 扩容
Function.c
void ADD()
{struct PeopleInfo person;printf(请输入姓名:);scanf(%s, person._name);printf(请输入年龄:);scanf(%d, person._age);printf(请输入号码:);scanf(%s, person._number);// 把个人信息添加到通讯录memmove(addressBook._PeoPleaddressBook._size,person,sizeof(person));addressBook._size;printf(添加成功\n); // 提示信息if (addressBook._size addressBook._capacity)Expansion(); // 扩容
} 如果满了就扩容
Address.h
#define EXP_CAPACITY 5 // 每次扩容的大小
Function.c
void Expansion()
{// 使用realloc保留原来的内容struct PeoPle* tmp (struct PeoPle*)realloc(addressBook._PeoPle, addressBook._capacity EXP_CAPACITY);if (tmp ! NULL)addressBook._PeoPle tmp;elseprintf(扩容失败\n);// 更新容量addressBook._capacity addressBook._capacity EXP_CAPACITY;printf(扩容成功当前容量%d\n,addressBook._capacity); // 提示信息
} 2-4.查看 查看功能可以查看已经添加的联系人的所有信息
Function.c
void DIS()
{printf(姓名 年龄 号码\n);for (int i 0; i addressBook._size; i){printf(%s %d %s\n,addressBook._PeoPle[i]._name, addressBook._PeoPle[i]._age, addressBook._PeoPle[i]._number);}
} 2-5.查找 查找是根据名字找到指向他信息的下标找不到返回-1
Function.c
int Find(const char* name)
{for (int i 0; i addressBook._size; i){if (strcmp(addressBook._PeoPle[i]._name, name) 0)return i;}printf(该联系人不存在\n);return -1;
} Select 函数中的case 3的部分做如下修改
case 3:printf(请输入要查找的联系人:);char name[20]; scanf(%s,name);int i Find(name);// 查找// 打印他的信息printf(姓名 年龄 号码\n);printf(%s %d %s\n, addressBook._PeoPle[i]._name, addressBook._PeoPle[i]._age, addressBook._PeoPle[i]._number);break; 2-6.删除 删除是根据名字删除指定的联系人所以可以复用查找函数
Function.c
void DEL()
{printf(请输入要删除的联系人:);char name[20];scanf(%s,name);int i Find(name);if (i 0){// i 位置之后先前覆盖一位就可以删除它了for (; i addressBook._size - 1; i){addressBook._PeoPle[i] addressBook._PeoPle[i 1];}addressBook._size--;printf(删除成功!\n);}
} 2-7.修改 修改也是先根据名字找到相应下标,然后再修改,所以也要复用查找函数:
Fuction.c
void MOD()
{printf(请输入要修改的联系人:);char name[20];scanf(%s, name);int i Find(name);if (i 0){printf(请修改姓名:);scanf(%s, addressBook._PeoPle[i]._name);printf(请修改年龄:);scanf(%d, (addressBook._PeoPle[i]._age));printf(请修改号码:);scanf(%s, addressBook._PeoPle-_number);printf(修改成功\n);}
} 2-8.退出 程序退出时需要把数据存储到文件中然后把堆区开辟的空间释放掉
Function.c
void EXIT()
{// 存储数据FILE* pf fopen(.//AddressBook.txt,wb); // 二进制写方式打开if (pf NULL){perror(文件打开失败\n);return;}for (int i 0; i addressBook._size; i){fwrite(addressBook._PeoPlei,sizeof(struct PeopleInfo),1 , pf);}fclose(pf);// 释放堆区空间free(addressBook._PeoPle);
} 至此代码已经编写完毕了可以测试程序了。
第三节测试 先添加3个人的信息最后输入0退出消息 打开文件看里面是否有内容 因为是二进制读写所以看不懂 再次运行程序看看文件中的信息能不能正确读取 最后测试删除、修改、查看就可以了这里不再掩饰。
每个文件的完整代码如下
main.c
#include Address.h
int main()
{AddressInit(); // 初始化Select(); // 打印菜单并选择return 0;
} Address.h
#define _CRT_SECURE_NO_WARNINGS
#includestdio.h
#includestdlib.h
#includestring.h
#define DEL_CAPACITY 10 // 默认初始容量
#define EXP_CAPACITY 5 // 每次扩容的大小
struct PeopleInfo // 一个人的信息
{char _name[20]; // 名字int _age; // 年龄char _number[20]; // 号码
};
struct AddressBook // 通讯录
{struct PeopleInfo* _PeoPle; // 所有人的信息int _capacity; // 通讯录的容量int _size; // 通讯录当前存储的数量
}addressBook;void printMenu(); // 打印菜单
void Select(); // 打印菜单并选择
void AddressInit(); // 初始化通讯录
void Expansion(); // 扩容
void ADD(); // 增加
void DIS(); // 查看
int Find(const char* name); // 查找
void DEL(); // 删除
void MOD(); // 修改
void EXIT(); // 保存释放
Function.c
#include Address.h
void AddressInit()
{FILE* pf fopen(.//AddressBook.txt,rb); // 二进制读方式打开if (pf NULL){perror(文件打开失败\n);return;}addressBook._capacity DEL_CAPACITY;addressBook._PeoPle (struct PeopleInfo*)malloc(addressBook._capacity*sizeof(struct PeopleInfo)); // 开辟空间if (addressBook._PeoPle NULL)return;addressBook._size 0;// 从文件中读取数据while (0 ! fread(addressBook._PeoPle addressBook._size, sizeof(struct PeopleInfo), 1, pf)){addressBook._size;if (addressBook._size addressBook._capacity)Expansion(); // 扩容函数之后实现}fclose(pf);
}void printMenu()
{printf(***********************************************\n);printf(***************1.增加*****2.删除***************\n);printf(***************3.查找*****4.修改***************\n);printf(***************5.查看*****0.退出***************\n);printf(***********************************************\n);
}void Select()
{printMenu(); // 打印菜单int select;while (1){printf(请选择:);scanf(%d, select);switch (select){case 1:ADD(); // 增加break;case 2:DEL(); // 删除break;case 3:printf(请输入要查找的联系人:);char name[20]; scanf(%s,name);int i Find(name);// 查找// 打印他的信息printf(姓名 年龄 号码\n);printf(%s %d %s\n, addressBook._PeoPle[i]._name, addressBook._PeoPle[i]._age, addressBook._PeoPle[i]._number);break;case 4:MOD(); // 修改 break;case 5:DIS(); // 查看break;case 0:EXIT();// 退出return 0;default:printf(非法的请求请重新输入:);}}
}void ADD()
{struct PeopleInfo person;printf(请输入姓名:);scanf(%s, person._name);printf(请输入年龄:);scanf(%d, person._age);printf(请输入号码:);scanf(%s, person._number);// 把个人信息添加到通讯录memmove(addressBook._PeoPleaddressBook._size,person,sizeof(person));addressBook._size;printf(添加成功\n); // 提示信息if (addressBook._size addressBook._capacity)Expansion(); // 扩容
}void Expansion()
{// 使用realloc保留原来的内容struct PeopleInfo* tmp (struct PeopleInfo*)realloc(addressBook._PeoPle, addressBook._capacity EXP_CAPACITY);if (tmp ! NULL)addressBook._PeoPle tmp;elseprintf(扩容失败\n);// 更新容量addressBook._capacity addressBook._capacity EXP_CAPACITY;printf(扩容成功当前容量%d\n,addressBook._capacity); // 提示信息
}void DIS()
{printf(姓名 年龄 号码\n);for (int i 0; i addressBook._size; i){printf(%s %d %s\n,addressBook._PeoPle[i]._name, addressBook._PeoPle[i]._age, addressBook._PeoPle[i]._number);}
}int Find(const char* name)
{for (int i 0; i addressBook._size; i){if (strcmp(addressBook._PeoPle[i]._name, name) 0)return i;}printf(该联系人不存在\n);return -1;
}void DEL()
{printf(请输入要删除的联系人:);char name[20];scanf(%s,name);int i Find(name);if (i 0){// i 位置之后先前覆盖一位就可以删除它了for (; i addressBook._size - 1; i){addressBook._PeoPle[i] addressBook._PeoPle[i 1];}addressBook._size--;printf(删除成功!\n);}
}void MOD()
{printf(请输入要修改的联系人:);char name[20];scanf(%s, name);int i Find(name);if (i 0){printf(请修改姓名:);scanf(%s, addressBook._PeoPle[i]._name);printf(请修改年龄:);scanf(%d, (addressBook._PeoPle[i]._age));printf(请修改号码:);scanf(%s, addressBook._PeoPle-_number);printf(修改成功\n);}
}void EXIT()
{// 存储数据FILE* pf fopen(.//AddressBook.txt,wb); // 二进制写方式打开if (pf NULL){perror(文件打开失败\n);return;}for (int i 0; i addressBook._size; i){fwrite(addressBook._PeoPlei,sizeof(struct PeopleInfo),1 , pf);}fclose(pf);// 释放堆区空间free(addressBook._PeoPle);
}
下期预告: 下一次是第十章,将学习预编译相关知识