目录
前面我们先用静态写了通讯录,后面改进换成了动态,但是我们发现还是有很大的问题,就是每次运行都要增加人员,非常的麻烦。
静态通讯录https://blog.csdn.net/m0_59952648/article/details/128495444?spm=1001.2014.3001.5501动态通讯录
https://blog.csdn.net/m0_59952648/article/details/128521081?spm=1001.2014.3001.5501
所以我们这次用文件处理,将增加的人员信息保存到文件中,下次运行直接从文件中提取人员信息,将会方便很多。
改进
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);
}