C语言《文件版本通讯录》
文章目录
- 普通版通讯录
- 动态版通讯录
- 文件版通讯录
- 一、文件版通讯录介绍
- 二、文件版通讯录实现
- (1)增加SavePhone保存函数
- (2)增加LoadPhone加载函数
- 三、文件版通讯录实现结果
- 四、实现源代码
- (1)phone.c
- (2)phone.h
- (3)test.c
普通版通讯录
[点击可查看普通版通讯录实现](https://blog.csdn.net/m0_59292239/article/details/127024944?spm=1001.2014.3001.5501)
动态版通讯录
[点击可查看动态版通讯录实现](https://blog.csdn.net/m0_59292239/article/details/127194385?spm=1001.2014.3001.5501)
文件版通讯录
一、文件版通讯录介绍
之前的版本,当通讯录退出后,录入的信息退出之后不能看到上次保存的信息,为了解决这个问题,把动态版升级为文件版通讯录。分两步实现,增加两个函数即可。
二、文件版通讯录实现
(1)增加SavePhone保存函数
void SavePhone(struct Phone*pc)
{
FILE* pf = fopen("data.txt", "wb");
if (pf == NULL)
{
perror("SavePhone");
return;
}
for (int i = 0; i<pc->sz; i++)
{
fwrite(pc->data+i,sizeof(struct P),1,pf);
}
fclose(pf);
pf = NULL;
}
第一步是当录入完信息后,把数据保存到文件中。先以二进制写的方式打开文件,此时没有这个文件。会在当前路径下创建一个这样的文件,判断pf是否为空,不为空,就for循环把信息写到这个文件中,用fwrtie函数进行写,pc->data,是连续空间的首地址,加i跳过i个元素,大小为struct P的大小,个数为1,写到pf流中,最后关闭文件。
(2)增加LoadPhone加载函数
void LoadPhone(struct Phone*pc)
{
FILE*pw=fopen("data.txt", "rb");
if (pw == NULL)
{
perror("LoadPhone");
return;
}
struct P tmp = { 0 };
while (fread(&tmp, sizeof(struct P), 1, pw))
{
check_cap(pc);
pc->data[pc->sz] = tmp;
pc->sz++;
}
fclose(pw);
pw = NULL;
}
第二步是下次运行该程序的时候,能够显示上次保存的数据。
在初始函数InitPhone增加一个加载函数 LoadPhone。先以二进制读的方式打开这个文件,判断pw是否为空,不为空,使用while循环进行把文件的信息录入(读)到通讯录中,用fread函数进行读,先创建一个结构体P的变量 tmp,先把文件中的信息读到tmp中,再把tmp放在pc->data[pc->sz]为pc->sz的位置上。又因为从文件录入的信息个数可能大于初始容量,所以要调用check_cap函数进行检查,如果不够就增容。
三、文件版通讯录实现结果
先录入信息,完之后退出,再运行该程序show查看保存的信息。
四、实现源代码
(1)phone.c
#include"phone.h"
static int check_cap(struct Phone * pc);
void LoadPhone(struct Phone*pc)
{
FILE*pw=fopen("data.txt", "rb");
if (pw == NULL)
{
perror("LoadPhone");
return;
}
struct P tmp = { 0 };
while (fread(&tmp, sizeof(struct P), 1, pw))
{
check_cap(pc);
pc->data[pc->sz] = tmp;
pc->sz++;
}
fclose(pw);
pw = NULL;
}
void InitPhone(struct Phone* pc)
{
assert(pc);
pc->data = (struct P *)malloc(sizeof(struct P) * De_sz);
if (pc->data == NULL)
{
perror("InitPhone");
return;
}
pc->sz = 0;
pc->cap = De_sz;
LoadPhone(pc);
}
int check_cap(struct Phone * pc)
{
if (pc->sz == pc->cap)
{
struct P *ptr = (struct P *)realloc(pc->data,sizeof(struct P)*(pc->cap + Add_sz));
if (ptr != NULL)
{
pc->data = ptr;
pc->cap += Add_sz;
printf("增容成功\n");
return 1;
}
else
{
perror("AddPhone");
return 0;
}
}
else
{
return 1;
}
}
void AddPhone(struct Phone* pc)
{
assert(pc);
if (check_cap(pc)==0)
{
return;
}
printf("输入名字:");
scanf("%s", pc->data[pc->sz].name);
printf("输入性别:");
scanf("%s", pc->data[pc->sz].sex);
printf("输入年龄:");
scanf("%d", &(pc->data[pc->sz].age));
printf("输入电话号码:");
scanf("%s", pc->data[pc->sz].tel);
printf("输入地址:");
scanf("%s", pc->data[pc->sz].adress);
pc->sz++;
printf("成功添加\n");
}
void ShowPhone(struct Phone* pc)
{
printf("%-20s\t%-5s\t%-10s\t%-13s\t%-30s\n", "姓名","性别","年龄","电话号码","地址");
for (int i = 0; i < pc->sz; i++)
{
printf("%-20s\t%-5s\t%-10d\t%-13s\t%-30s\n", pc->data[i].name, pc->data[i].sex,
pc->data[i].age, pc->data[i].tel, pc->data[i].adress);
}
}
int Find_name(struct Phone* pc, char name[])
{
for (int i = 0; i < pc->sz; i++)
{
if (strcmp(pc->data[i].name, name) == 0)
{
return i;
}
}
return -1;
}
void DelPhone(struct Phone* pc)
{
char name[MAX_name];
printf("输入删除的名字:");
scanf("%s", name);
int ret = Find_name(pc, name);
if (ret == -1)
{
printf("删除的人不存在");
}
else
{
for (int j = ret; j < pc->sz; j++)
{
pc->data[j] = pc->data[j + 1];
}
pc->sz--;
printf("已删除改联系人\n");
}
}
void ModifyPhone(struct Phone* pc)
{
char name[MAX_name];
printf("输入修改的名字:");
scanf("%s", name);
int ret = Find_name(pc, name);
if (ret == -1)
{
printf("修改的人不存在");
}
else
{
printf("输入名字:");
scanf("%s", pc->data[ret].name);
printf("输入性别:");
scanf("%s", pc->data[ret].sex);
printf("输入年龄:");
scanf("%d", &(pc->data[ret].age));
printf("输入电话号码:");
scanf("%s", pc->data[ret].tel);
printf("输入地址:");
scanf("%s", pc->data[ret].adress);
printf("已修改改联系人\n");
}
}
int cmp_name(const void* e1,const void* e2)
{
return strcmp(((struct P*)e1)->name ,((struct P*)e2)->name);
}
void SortPhone(struct Phone* pc)
{
qsort(pc->data,pc->sz,sizeof(struct P),cmp_name);
}
void SearchPhone(struct Phone* pc)
{
char name[MAX_name];
printf("输入搜索的名字:");
scanf("%s", name);
int ret = Find_name(pc, name);
if (ret == -1)
{
printf("搜索的人不存在");
}
else
{
printf("%-20s\t%-5s\t%-10s\t%-13s\t%-30s\n", "姓名", "性别", "年龄", "电话号码", "地址");
printf("%-20s\t%-5s\t%-10d\t%-13s\t%-30s\n", pc->data[ret].name, pc->data[ret].sex,
pc->data[ret].age, pc->data[ret].tel, pc->data[ret].adress);
}
}
void DestroyPhone(struct Phone*pc)
{
free(pc->data);
pc->data = NULL;
pc->cap = 0;
pc->sz = 0;
}
void SavePhone(struct Phone*pc)
{
FILE* pf = fopen("data.txt", "wb");
if (pf == NULL)
{
perror("SavePhone");
return;
}
for (int i = 0; i<pc->sz; i++)
{
fwrite(pc->data+i,sizeof(struct P),1,pf);
}
fclose(pf);
pf = NULL;
}
(2)phone.h
#pragma once
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<assert.h>
#define MAX_name 20
#define MAX_sex 5
#define MAX_tel 13
#define MAX_addr 30
#define De_sz 3
#define Add_sz 2
struct P
{
char name[MAX_name];
char sex[MAX_sex];
int age;
char tel[MAX_tel];
char adress[MAX_addr];
};
struct Phone
{
struct P *data;
int sz;
int cap;
};
void InitPhone(struct Phone* pc);
void AddPhone(struct Phone* pc);
void DelPhone(struct Phone* pc);
void SearchPhone(struct Phone* pc);
void ModifyPhone(struct Phone* pc);
void ShowPhone(struct Phone* pc);
void SortPhone(struct Phone* pc);
int Find_name(struct Phone* pc, char name[]);
int cmp_name(const void* e1, const void* e2);
int check_cap(struct Phone * pc);
void DestroyPhone(struct Phone*pc);
void SavePhone(struct Phone*pc);
void LoadPhone(struct Phone*pc);
(3)test.c
#include"phone.h"
void menu()
{
printf("***************************************\n");
printf("******* 1、add 2、del *******\n");
printf("******* 3、search 4、modify *******\n");
printf("******* 5、show 6、sort *******\n");
printf("******* 0、exit *******\n");
printf("***************************************\n");
}
int main()
{
int input = 0;
struct Phone con;
InitPhone(&con);
do
{
menu();
printf("请选择->");
scanf("%d", &input);
switch (input)
{
case 1:
AddPhone(&con);
break;
case 2:
DelPhone(&con);
break;
case 3:
SearchPhone(&con);
break;
case 4:
ModifyPhone(&con);
break;
case 5:
ShowPhone(&con);
break;
case 6:
SortPhone(&con);
break;
case 0:
SavePhone(&con);
DestroyPhone(&con);
printf("退出成功\n");
break;
default:
printf("选择错误\n");
break;
}
} while (input);
return 0;
}