目录
前面我们先用静态写了通讯录,后面改进换成了动态,但是我们发现还是有很大的问题,就是每次运行都要增加人员,非常的麻烦。
所以我们这次用文件处理,将增加的人员信息保存到文件中,下次运行直接从文件中提取人员信息,将会方便很多。
改进
1.读取信息
void LoadContact(Contact *pcont) { assert(pcont != NULL); FILE *fp = fopen("cont.dat", "r"); if (fp == NULL) { printf("读取通讯录文件失败.....\n"); return; } int idx = 0; while (1) { if (IsFullContact(pcont) && !_Inc(pcont)) break; int res = fscanf(fp, "%s %s %d %s %s", pcont->cont[idx].name, pcont->cont[idx].sex, &pcont->cont[idx].age, pcont->cont[idx].tel, pcont->cont[idx].address); if (res == EOF) break; idx++; pcont->size++; } fclose(fp); }
2.写入信息
void SaveContact(Contact *pcont) { assert(pcont != NULL); FILE *fp = fopen("cont.dat", "w"); if (fp == NULL) { printf("写入通讯录文件失败.....\n"); return; } for (int i = 0; i<pcont->size; ++i) { fprintf(fp, "%-10s%-5s%-6d%-13s%s\n", pcont->cont[i].name, pcont->cont[i].sex, pcont->cont[i].age, pcont->cont[i].tel, pcont->cont[i].address); } fclose(fp); #ifdef DISPLAY printf("写入数据成功.\n"); #endif }
完整代码
config.h
#ifndef _CONFIG_H_ #define _CONFIG_H_ //#define DISPLAY #endif /* _CONFIG_H_ */
utili.h
#ifndef _UTILI_H_ #define _UTILI_H_ #include<stdio.h> #include<assert.h> #include<string.h> #include<stdbool.h> #include<malloc.h> #endif /* _UTILI_H_ */
contact.h
#ifndef _CONTACT_H_ #define _CONTACT_H_ #include"utili.h" enum { QUIT, ADD, DEL, FIND, MODIFY, SHOW, CLEAR, SORT }; #define MAX_NAME_SIZE 10 #define MAX_SEX_SIZE 3 #define MAX_TEL_SIZE 12 #define MAX_ADDR_SIZE 128 //#define MAX_CONTACT_SIZE 2 #define DEFAULT_CONTACT_SIZE 2 //定义通讯录人员信息 typedef struct PersonInfo { char name[MAX_NAME_SIZE]; char sex[MAX_SEX_SIZE]; int age; char tel[MAX_TEL_SIZE]; char address[MAX_ADDR_SIZE]; }PersonInfo; //定义通讯录结构 typedef struct Contact { //PersonInfo cont[MAX_CONTACT_SIZE]; //静态开辟 PersonInfo *cont; //动态开辟 size_t capacity; size_t size; }Contact; ///////////////////////////////////////////////////////////// bool IsFullContact(Contact *pcont); void InitContact(Contact *pcont); void AddContact(Contact *pcont); void ShowContact(Contact *pcont); int FindContact(Contact *pcont); void DelContact(Contact *pcont); void ModifyContact(Contact *pcont); void SortContact(Contact *pcont); void ClearContact(Contact *pcont); void DestroyContact(Contact *pcont); //数据序列化 void SaveContact(Contact *pcont); void LoadContact(Contact *pcont); #endif /* _UTILI_H_ */
contact.cpp
#include"contact.h" #include"config.h" void InitContact(Contact *pcont) { assert(pcont != NULL); pcont->cont = (PersonInfo*)malloc(sizeof(PersonInfo)* DEFAULT_CONTACT_SIZE); memset(pcont->cont, 0, sizeof(PersonInfo)* DEFAULT_CONTACT_SIZE); pcont->capacity = DEFAULT_CONTACT_SIZE; pcont->size = 0; ///////////////////////////////////////////////////////////////////////////// LoadContact(pcont); } static bool _Inc(Contact *pcont) { PersonInfo *new_cont = (PersonInfo *)realloc(pcont->cont, sizeof(PersonInfo)*(pcont->capacity * 2)); if (new_cont == NULL) { printf("内存不足,扩容失败......\n"); return false; } pcont->cont = new_cont; pcont->capacity *= 2; return true; } bool IsFullContact(Contact *pcont) { assert(pcont != NULL); return pcont->size >= pcont->capacity; } void AddContact(Contact *pcont) { assert(pcont != NULL); if (IsFullContact(pcont) && !_Inc(pcont)) { printf("通讯录空间已满,不能新增信息.....\n"); return; } printf("姓名:>"); scanf("%s", pcont->cont[pcont->size].name); printf("性别:>"); scanf("%s", pcont->cont[pcont->size].sex); printf("年龄:>"); scanf("%d", &pcont->cont[pcont->size].age); printf("电话:>"); scanf("%s", pcont->cont[pcont->size].tel); printf("住址:>"); scanf("%s", pcont->cont[pcont->size].address); pcont->size++; #ifdef DISPLAY printf("增加完成.......\n"); #endif } void ShowContact(Contact *pcont) { assert(pcont != NULL); printf("%-10s%-5s%-6s%-13s%s\n", "姓名", "性别", "年龄", "电话", "住址"); for (int i = 0; i<pcont->size; ++i) { printf("%-10s%-5s%-6d%-13s%s\n", pcont->cont[i].name, pcont->cont[i].sex, pcont->cont[i].age, pcont->cont[i].tel, pcont->cont[i].address); } } int FindContact(Contact *pcont) { assert(pcont != NULL); printf("请输入要查找的姓名:>"); char name[MAX_NAME_SIZE] = { 0 }; scanf("%s", name); printf("%-10s%-5s%-6s%-13s%s\n", "姓名", "性别", "年龄", "电话", "住址"); for (int i = 0; i<pcont->size; ++i) { if (strcmp(name, pcont->cont[i].name) == 0) { printf("%-10s%-5s%-6d%-13s%s\n", pcont->cont[i].name, pcont->cont[i].sex, pcont->cont[i].age, pcont->cont[i].tel, pcont->cont[i].address); return i; } } return -1; } void DelContact(Contact *pcont) { assert(pcont != NULL); printf("请输入要删除的名字:>"); char name[MAX_NAME_SIZE] = { 0 }; scanf("%s", name); int i; for (i = 0; i<pcont->size; ++i) { if (strcmp(name, pcont->cont[i].name) == 0) break; } if (i >= pcont->size) { printf("要删除的信息不存在.....\n"); return; } for (int k = i; k<pcont->size - 1; ++k) pcont->cont[k] = pcont->cont[k + 1]; pcont->size--; #ifdef DISPLAY printf("删除完成.......\n"); #endif } void ModifyContact(Contact *pcont) { assert(pcont != NULL); printf("请输入要修改的名字:>"); char name[MAX_NAME_SIZE] = { 0 }; scanf("%s", name); int i; for (i = 0; i<pcont->size; ++i) { if (strcmp(name, pcont->cont[i].name) == 0) break; } if (i >= pcont->size) { printf("要修改的信息不存在.....\n"); return; } printf("你想修改什么信息(1-姓名 2-性别 3-年龄 4-电话 5-住址)\n"); int select; scanf("%d", &select); if (select == 1) { printf("请输入要修改姓名:>"); scanf("%s", pcont->cont[i].name); } else if (select == 2) { printf("请输入要修改性别:>"); scanf("%s", pcont->cont[i].sex); } else if (select == 3) { printf("请输入要修改住址:>"); scanf("%d", &pcont->cont[i].age); } else if (select == 4) { printf("请输入要修改电话:>"); scanf("%s", pcont->cont[i].tel); } else if (select == 5) { printf("请输入要修改性别:>"); scanf("%s", pcont->cont[i].address); } #ifdef DISPLAY printf("修改完成.......\n"); #endif } void SortContact(Contact *pcont) { assert(pcont != NULL); for (int i = 0; i<pcont->size - 1; ++i) { for (int j = 0; j<pcont->size - 1 - i; ++j) { if (strcmp(pcont->cont[j].name, pcont->cont[j + 1].name) > 0) { PersonInfo tmp = pcont->cont[j]; pcont->cont[j] = pcont->cont[j + 1]; pcont->cont[j + 1] = tmp; } } } #ifdef DISPLAY printf("排序完成.......\n"); #endif } void ClearContact(Contact *pcont) { assert(pcont != NULL); pcont->size = 0; #ifdef DISPLAY printf("清除完成.......\n"); #endif } void DestroyContact(Contact *pcont) { assert(pcont != NULL); free(pcont->cont); pcont->cont = NULL; pcont->capacity = pcont->size = 0; #ifdef DISPLAY printf("摧毁通讯录成功.\n"); #endif } void LoadContact(Contact *pcont) { assert(pcont != NULL); FILE *fp = fopen("cont.dat", "r"); if (fp == NULL) { printf("读取通讯录文件失败.....\n"); return; } int idx = 0; while (1) { if (IsFullContact(pcont) && !_Inc(pcont)) break; int res = fscanf(fp, "%s %s %d %s %s", pcont->cont[idx].name, pcont->cont[idx].sex, &pcont->cont[idx].age, pcont->cont[idx].tel, pcont->cont[idx].address); if (res == EOF) break; idx++; pcont->size++; } fclose(fp); } void SaveContact(Contact *pcont) { assert(pcont != NULL); FILE *fp = fopen("cont.dat", "w"); if (fp == NULL) { printf("写入通讯录文件失败.....\n"); return; } for (int i = 0; i<pcont->size; ++i) { fprintf(fp, "%-10s%-5s%-6d%-13s%s\n", pcont->cont[i].name, pcont->cont[i].sex, pcont->cont[i].age, pcont->cont[i].tel, pcont->cont[i].address); } fclose(fp); #ifdef DISPLAY printf("写入数据成功.\n"); #endif }
contactMain.cpp
#include"contact.h" void Menu() { printf("****************通 讯 录****************\n"); printf("* [1] Add [2] Del *\n"); printf("* [3] Find [4] Modify *\n"); printf("* [5] Show [6] Clear *\n"); printf("* [7] Sort [0] Quit *\n"); printf("****************************************\n"); } void main() { Contact cont; InitContact(&cont); int select = 1; while (select) { Menu(); printf("请选择:>"); scanf("%d", &select); if (select == QUIT) break; switch (select) { case ADD: AddContact(&cont); break; case DEL: DelContact(&cont); break; case FIND: FindContact(&cont); break; case MODIFY: ModifyContact(&cont); break; case SHOW: ShowContact(&cont); break; case CLEAR: ClearContact(&cont); break; case SORT: SortContact(&cont); //qsort break; } } SaveContact(&cont); DestroyContact(&cont); }