动态文件通讯录
无论是静态通讯录还是动态的通讯录其实都是在内存里面,第二次打开后之前的数据就全都没有了,那么这次我们让数据储存到文件里。
contacts.c
void stockpilecontact(contacts* pc) { assert(pc != NULL); FILE* p1 = fopen("contacts.txt", "wb");//打开文件,以二进制方式写 if (p1 == NULL) { perror("SaveContact"); return; } int i = 0; for (i = 0; i < pc->count; i++)//输入通讯录中的成员信息 { fwrite(pc->data + i, sizeof(person), 1, p1); } fclose(p1);//关闭文件 p1 = NULL; }
运行之后我们添加三个人的信息
然后打开我们的文件目录来看看:
这个就是我们刚刚生成的文件,里面有我们输入三个联系人的信息:
有些地方是乱码看不懂是因为这是以二进制形式输入。
现在我们想办法让这个通讯录读取这些联系人。
打开文件的地方当然要在初始化通讯录的时候读取文件内容。
读取要注意,我们把读取的联系人存在内存时,要先判断能不能放的下,放不下就要增容。
contacts.c
void capacity_increase(contacts* pc)//增容 { if (pc->count == pc->capacity) { person* str = (person*)realloc(pc->data, sizeof(person) * (pc->capacity + 2)); if (str == NULL) { printf("addcontact:%s", strerror(errno)); return 1; } else { pc->data = str; pc->capacity += 2; } printf("增容成功\n"); } } void uploadcontacts(contacts* pc)//读取联系人函数 { FILE* p2 = fopen("contacts.txt", "rb");//打开文件二进制方式读 if (p2 == NULL) { perror("OpenContacts"); return 1; } person arr = { 0 };//文件读取数据的储存位置 while (fread(&arr, sizeof(person), 1, p2)) { capacity_increase(pc);//判断是否需要增容 pc->data[pc->count] = arr;//存入内存中 pc->count++; } fclose(p2);//关闭文件 p2=NULL; } int initialize(contacts* pc) { assert(pc != NULL); pc->count = 0;//将计数的变量初始化为0 pc->data = (person*)calloc(3,sizeof(person)); if (pc->data == NULL) { printf("initialize:%s",strerror(errno)); return 1; } pc->capacity = 3; uploadcontacts(pc);// 读取通讯录 return 0; }
运行一下看看:
有上次输入的联系人。
我又添加了一个联系人,之后退出,再次打开然后展示:
完整版代码
contacts.h
#include <stdio.h> #include <string.h> #include <assert.h> #include <stdlib.h> #define MAX 100//通讯录最大人数 //定义的结构体 typedef struct person { char name[20];//名字 int age;//年龄 char sex[20];//性别 char phone[20];//电话 char location[20];//住址 }person; typedef struct contacts { person* data;//存放人信息的位置 int count;//记录通讯录的人数 int capacity;//记录当前通讯录有多少人 }contacts; //函数声明区 int initialize(contacts* pc);//初始化通讯录 int addcontact(contacts* pc);//输入联系人信息 void showcontact(const contacts* pc);//打印通讯录 int delcontact(contacts* pc);//删除联系人 int modifycontact(contacts* pc);//修改联系人信息 int findcontact(contacts* pc);//查找联系人 void sortcontact(contacts* pc);//排序通讯录 void destroycontact(contacts* pc);//动态内存销毁 void stockpilecontact(contacts* pc);//储存到文件里 void uploadcontacts(contacts* pc);//读取文件
contacts.c
#include "contacts.h" int find_out(char* p1, contacts* p2) { assert(p1 != NULL); assert(p2 != NULL); int i = 0; for (i = 0; i < p2->count; i++) { if (!strcmp(p1, p2->data[i].name))//如果相等就返回0,前面加了!操作符,所以非零条件不成立 return i; } return -1; } void capacity_increase(contacts* pc)//增容 { if (pc->count == pc->capacity) { person* str = (person*)realloc(pc->data, sizeof(person) * (pc->capacity + 2)); if (str == NULL) { printf("addcontact:%s", strerror(errno)); return 1; } else { pc->data = str; pc->capacity += 2; } printf("增容成功\n"); } } void uploadcontacts(contacts* pc)//读取联系人函数 { FILE* p2 = fopen("contacts.txt", "rb");//打开文件二进制方式读 if (p2 == NULL) { perror("OpenContacts"); return 1; } person arr = { 0 }; while (fread(&arr, sizeof(person), 1, p2)) { capacity_increase(pc);//判断是否需要增容 pc->data[pc->count] = arr; pc->count++; } fclose(p2);//关闭文件 p2 = NULL; } int initialize(contacts* pc) { assert(pc != NULL); pc->count = 0;//将计数的变量初始化为0 pc->data = (person*)calloc(3,sizeof(person)); if (pc->data == NULL) { printf("initialize:%s",strerror(errno)); return 1; } pc->capacity = 3; uploadcontacts(pc);// 读取通讯录 return 0; } int addcontact(contacts* pc) { assert(pc != NULL);//断言pc指向的位置不是空指针 capacity_increase(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].phone); printf("家庭住址:"); scanf("%s", pc->data[pc->count].location); pc->count++; printf("增加成功\n"); } void showcontact(const contacts* pc) { assert(pc != NULL); int i = 0; printf("%-20s\t%-20s\t%-20s\t%-20s\t%-20\t\n", "姓名", "年龄", "性别", "电话号", "家庭住址"); for (i = 0; i < pc->count; i++) { printf("%-20s\t%-20d\t%-20s\t%-20s\t%-20\t\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].phone, pc->data[i].location); } } int delcontact(contacts* pc) { assert(pc != NULL); char name[20] = { 0 }; printf("输入此人姓名\n"); scanf("%s", name); int i = find_out(name, pc); if (i == -1) { printf("无此人信息\n"); return 1; } pc->count = pc->count - 1; while (i < pc->count) { pc->data[i] = pc->data[i + 1]; i++; } printf("删除成功\n"); } int modifycontact(contacts* pc) { assert(pc != NULL); printf("输入此人姓名\n"); char name[20] = { 0 }; scanf("%s", name); int i = find_out(name, pc); if (i == -1) { printf("无此人信息\n"); return 1; } printf("请输入要修改的信息\n"); printf("姓名:"); scanf("%s", pc->data[i].name); printf("年龄:"); scanf("%d", &(pc->data[i].age)); printf("性别:"); scanf("%s", pc->data[i].sex); printf("电话号:"); scanf("%s", pc->data[i].phone); printf("家庭住址:"); scanf("%s", pc->data[i].location); printf("修改成功\n"); } int findcontact(contacts* pc) { assert(pc != NULL); printf("输入此人姓名\n"); char name[20] = { 0 }; scanf("%s", name); int i = find_out(name, pc); if (i == -1) { printf("无此人信息\n"); return 1; } printf("%-20s\t%-20s\t%-20s\t%-20s\t%-20\t\n", "姓名", "年龄", "性别", "电话号", "家庭住址"); printf("%-20s\t%-20d\t%-20s\t%-20s\t%-20\t\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].phone, pc->data[i].location); } int estimate(const void* p1, const void* p2) { return strcmp(((person*)p1)->name, ((person*)p2)->name); } void sortcontact(contacts* pc) { assert(pc != NULL); qsort(pc->data, pc->count, sizeof(person), estimate); printf("排序成功\n"); } void destroycontact(contacts* pc) { assert(pc != NULL); free(pc->data); pc->data = NULL; } void stockpilecontact(contacts* pc) { assert(pc != NULL); FILE* p1 = fopen("contacts.txt", "wb");//打开文件,以二进制方式写 if (p1 == NULL) { perror("SaveContact"); return; } int i = 0; for (i = 0; i < pc->count; i++)//输入通讯录中的成员信息 { fwrite(pc->data + i, sizeof(person), 1, p1); } fclose(p1);//关闭文件 p1 = NULL; }
test.c
#include "contacts.h" enum list { EXIT, ADD, DEL, MODIFY, FIND, SHOW, SORT }; void catalogue() { printf("*********************************\n"); printf("*** 1.add 2.del ***\n"); printf("*** 3.modify 4.find ***\n"); printf("*** 5.show 6.sort ***\n"); printf("*** 0.exit ***\n"); printf("*********************************\n"); } int main() { int n = 0; contacts con;//通讯录 initialize(&con);//初始换通讯录 do { catalogue();//通讯录菜单 printf("请选择>"); scanf("%d", &n);//选择要做什么 switch (n) { case EXIT://退出程序 stockpilecontact(&con); destroycontact(&con); printf("退出通讯录\n"); break; case ADD://添加联系人 addcontact(&con); break; case DEL://删除联系人 delcontact(&con); break; case FIND://查找联系人 findcontact(&con); break; case MODIFY://修改联系人信息 modifycontact(&con); break; case SHOW://展示联系人 showcontact(&con); break; case SORT://排序通讯录 sortcontact(&con); break; default: printf("输入错误请重新输入\n"); } } while (n); return 0; }