文章目录
- 🚩前言
- 🧩框架结构
- 📺效果展示
- 🚀完整代码
🚩前言
我们前面写的两种方法(静态和动态),唯一缺点就是每次运行都要输入新的数据,很麻烦,也就是说写入的数据无法长久保存,代码运行结束后就立即释放了。所以,接下来就用文件操作的知识点,把写入的数据导入到文件中去。
🧩框架结构
由于我在前面的两篇文章中说了具体的项目需求,因此在这片当中我直接说编写代码的不同点。
文件编写通讯录,主要是多了文件读操作、写操作2个部分,下面就是这2个代码块,注意的就是文件记得即使关闭。
写操作,把数据录入到文件中去。
//文件写操作函数
void save_contact(ConSL* con)
{
assert(con);
FILE* pf_wirte = fopen("contact_data.txt", "wb");
if (pf_wirte == NULL)
{
perror("save_contact fopen error!\n");
return;
}
//写入 文件中
for (int i = 0; i < con->size; i++)
{
fwrite(con->data+i, sizeof(PeoInfo), 1, pf_wirte);
//把每个结构体类型中的信息写入到文件中去
}
printf("数据保存成功!\n");
//关闭
fclose(pf_wirte);
pf_wirte = NULL;
}
读操作,把文件中的信息显示到控制台上。
//文件读操作函数
void load_contact(ConSL* con)
{
PeoInfo temp = { 0 };//临时变量
assert(con);
FILE* pf_read = fopen("contact_data.txt", "rb");
if (pf_read == NULL)
{
perror("load_contact fopen error!\n");
return;
}
//循环读取文件中的内容
while (fread(&temp,sizeof(PeoInfo),1,pf_read))//返回0的时候就读取完了
{
//读的时候,需要判断文件中的数据个数,在申请的空间中是否能存储完
check_capacity(con);
//用临时变量存储,再赋值给申请的空间中去
con->data[con->size++] = temp;
}
//记得关闭文件
fclose(pf_read);
pf_read = NULL;
}
📺效果展示
直接显示数据,就可以查看文件中的信息了
🚀完整代码
Contact.h头文件
#pragma once
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<conio.h>
#include<Windows.h>
#define NAME_MAX 100
#define AGE_MAX 3
#define SEX_MAX 4
#define TEL_MAX 20
#define ADDR_MAX 40
//枚举功能
enum address_book
{
Exit,
Add,
Delete,
Find,
Modify,
Sort,
Show,
Save
};
//通讯录联系人信息
typedef struct Person
{
char Name[NAME_MAX];
char Age[AGE_MAX];
char Gender[SEX_MAX];
char Tel[TEL_MAX];
char Address[ADDR_MAX];
}PeoInfo;
//顺序表结构体
typedef struct contact_seq_list
{
PeoInfo* data;
int capacity;//空间容量大小
int size;//有效元素个数
}ConSL;
void init_contact(ConSL* con);//初始化函数
void load_contact(ConSL* con);//文件读操作函数
void save_contact(ConSL* con);//文件写操作函数
void addition_contact(ConSL* con);//添加函数
void delete_contact(ConSL* con);//删除函数
void show_contact(ConSL* con);//打印函数
void find_contact(ConSL* con);//查找函数
void modify_contact(ConSL* con);//修改函数
void sort_contact(ConSL* con);//排序函数
void save_contact(ConSL* con);//保存函数
void destroy_contact(ConSL* con);//销毁函数
Contact.c源文件
#define _CRT_SECURE_NO_WARNINGS 1
#include "Contact.h"
void check_capacity(ConSL* ptr);//声明一下
//文件读操作函数
void load_contact(ConSL* con)
{
PeoInfo temp = { 0 };//临时变量
assert(con);
FILE* pf_read = fopen("contact_data.txt", "rb");
if (pf_read == NULL)
{
perror("load_contact fopen error!\n");
return;
}
//循环读取文件中的内容
while (fread(&temp,sizeof(PeoInfo),1,pf_read))//返回0的时候就读取完了
{
check_capacity(con);
con->data[con->size++] = temp;
}
fclose(pf_read);
pf_read = NULL;
}
//文件写操作函数
void save_contact(ConSL* con)
{
assert(con);
FILE* pf_wirte = fopen("contact_data.txt", "wb");
if (pf_wirte == NULL)
{
perror("save_contact fopen error!\n");
return;
}
//写入 文件中
for (int i = 0; i < con->size; i++)
{
fwrite(con->data+i, sizeof(PeoInfo), 1, pf_wirte);
}
printf("数据保存成功!\n");
//关闭
fclose(pf_wirte);
pf_wirte = NULL;
}
//初始化函数
void init_contact(ConSL* con)
{
con->data = NULL;
con->capacity = con->size = 0;
//文件加载
load_contact(con);
}
void check_capacity(ConSL* ptr)
{
if (ptr->capacity == ptr->size)
{
//说明空间为空或者满了,则需要扩容
int new_capacity = ptr->capacity == 0 ? 4 : 2 * ptr->capacity;
PeoInfo* temp = (PeoInfo*)realloc(ptr->data, new_capacity * sizeof(PeoInfo));
if (temp == NULL)
{
perror("realloc fail!");
exit(1);
}
ptr->data = temp;
ptr->capacity = new_capacity;
}
}
//添加函数
void addition_contact(ConSL* con)
{
assert(con);
//添加时必须判断是否满
check_capacity(con);
//添加数据
printf("联系人信息录入中……\n");
printf("请输入姓名:");
scanf("%s", con->data[con->size].Name);
printf("请输入年龄:");
scanf("%s", con->data[con->size].Age);
printf("请输入性别:");
scanf("%s", con->data[con->size].Gender);
printf("请输入电话:");
scanf("%s", con->data[con->size].Tel);
printf("请输入地址:");
scanf("%s", con->data[con->size].Address);
//元素个数自增
con->size++;
printf("添加成功!\n");
}
//打印函数
void show_contact(ConSL* con)
{
//assert(con.size);
if (con->size == 0)
{
printf("通讯录为空,无法显示!\n");
return;
}
printf("通讯录总人数:%d\n", con->size);
printf("*************************************************************************************************\n");
printf("***************************** 通讯录信息 ***************************************\n");
printf("*************************************************************************************************\n");
printf("-------------------------------------------------------------------------------------------------\n");
printf("|%-12s\t%-3s\t%-4s\t%-12s\t\t%-40s|\n", "姓名", "年龄", "性别", "电话", "地址");
for (int i = 0; i < con->size; i++)
{
printf("|%-12s\t%-3s\t%-4s\t%-12s\t\t%-40s|\n", con->data[i].Name
, con->data[i].Age
, con->data[i].Gender
, con->data[i].Tel
, con->data[i].Address);
}
printf("-------------------------------------------------------------------------------------------------\n");
}
static int find_information(ConSL* ptr,char* name)
{
for (int i = 0; i < ptr->size; i++)
{
if (strcmp(ptr->data[i].Name, name) == 0)
{
return i;
}
}
return -1;
}
//删除函数
void delete_contact(ConSL* con)
{
//assert(con&&con->size);
assert(con);
if (con->size == 0)
{
printf("通讯录为空,无法删除!\n");
return;
}
printf("请输入要删除的联系人的姓名:\n");
char name[NAME_MAX];
scanf("%s", name);
int ret=find_information(con, name);
if (ret == -1)
{
printf("没找到!\n");
return;
}
for (int i = ret; i < con->size - 1; i++)
{
con->data[i] = con->data[i + 1];
}
con->size--;
printf("删除成功!\n");
show_contact(con);
}
//查找函数
void find_contact(ConSL* con)
{
assert(con);
if (con->size == 0)
{
printf("通讯录为空,无法查找!\n");
return;
}
printf("请输入要查找的联系人的姓名:\n");
char name[NAME_MAX];
scanf("%s", name);
int ret=find_information(con, name);
if (ret == -1)
{
printf("没查到!\n");
return;
}
printf("-------------------------------------------------------------------------------------------------\n");
printf("|%-12s\t%-3s\t%-4s\t%-12s\t\t%-40s|\n", "姓名", "年龄", "性别", "电话", "地址");
printf("|%-12s\t%-3s\t%-4s\t%-12s\t\t%-40s|\n", con->data[ret].Name
, con->data[ret].Age
, con->data[ret].Gender
, con->data[ret].Tel
, con->data[ret].Address);
printf("-------------------------------------------------------------------------------------------------\n");
}
//修改函数
void modify_contact(ConSL* con)
{
assert(con);
if (con->size == 0)
{
printf("通讯录为空,无法修改!\n");
return;
}
printf("请输入要修改的联系人的姓名:\n");
char name[NAME_MAX];
scanf("%s", name);
int ret = find_information(con, name);
if (ret == -1)
{
printf("没找到,无法修改!\n");
return;
}
printf("修改进行中………\n");
printf("请输入新的姓名:");
scanf("%s", con->data[ret].Name);
printf("请输入新的年龄:");
scanf("%s", con->data[ret].Age);
printf("请输入新的性别:");
scanf("%s", con->data[ret].Gender);
printf("请输入新的电话:");
scanf("%s", con->data[ret].Tel);
printf("请输入新的地址:");
scanf("%s", con->data[ret].Address);
printf("修改成功!\n");
show_contact(con);
}
int compar_by_name(const void* e1, const void* e2)
{
return strcmp(((PeoInfo*)e1)->Name, ((PeoInfo*)e2)->Name);
}
int compar_by_age(const void* e1, const void* e2)
{
return strcmp(((PeoInfo*)e1)->Age, ((PeoInfo*)e2)->Age);
}
//排序函数
void sort_contact(ConSL* con)
{
assert(con);
if (con->size == 0)
{
printf("通讯录为空,无法排序!\n");
return;
}
printf("请选择排序方式:1、按照姓名排序,2、按照年龄排序。\n");
int select1 = 0;
scanf("%d", &select1);
if (select1 == 1)
{
qsort(con->data, con->size, sizeof(PeoInfo), compar_by_name);
printf("排序成功!\n");
}
if (select1 == 2)
{
qsort(con->data, con->size, sizeof(PeoInfo), compar_by_age);
printf("排序成功!\n");
}
}
//销毁函数
void destroy_contact(ConSL* con)
{
if (con->data)
{
free(con->data);
}
con->data = NULL;
}
test_contact.c源文件
#define _CRT_SECURE_NO_WARNINGS 1
#include"Contact.h"
void menu()
{
printf("\t\t\t\t\t***************************************\n");
printf("\t\t\t\t\t********* 通讯录 *********\n");
printf("\t\t\t\t\t***************************************\n");
printf("\t\t\t\t\t**** ——> 1、添加联系人 <—— ****\n");
printf("\t\t\t\t\t***************************************\n");
printf("\t\t\t\t\t**** ——> 2、删除联系人 <—— ****\n");
printf("\t\t\t\t\t***************************************\n");
printf("\t\t\t\t\t**** ——> 3、查找联系人 <—— ****\n");
printf("\t\t\t\t\t***************************************\n");
printf("\t\t\t\t\t**** ——> 4、修改联系人 <—— ****\n");
printf("\t\t\t\t\t***************************************\n");
printf("\t\t\t\t\t**** ——> 5、通讯录排序 <—— ****\n");
printf("\t\t\t\t\t***************************************\n");
printf("\t\t\t\t\t**** ——> 6、显示联系人 <—— ****\n");
printf("\t\t\t\t\t***************************************\n");
printf("\t\t\t\t\t**** ——> 7、保存联系人 <—— ****\n");
printf("\t\t\t\t\t***************************************\n");
printf("\t\t\t\t\t**** ——> 0、退出通讯录 <—— ****\n");
printf("\t\t\t\t\t***************************************\n");
}
void test()
{
ConSL con;
init_contact(&con);
int input = 0;
while (1)
{
menu();
printf("请选择功能:\n");
scanf("%d", &input);
switch (input)
{
case Exit:
save_contact(&con);
destroy_contact(&con);
printf("欢迎下次使用!\n");
exit(1);
case Add:
addition_contact(&con);
break;
case Delete:
delete_contact(&con);
break;
case Find:
find_contact(&con);
break;
case Modify:
modify_contact(&con);
break;
case Sort:
sort_contact(&con);
break;
case Show:
show_contact(&con);
break;
case Save:
save_contact(&con);
break;
default:
printf("选择错误,请重新选择:\n");
break;
}
_getch();
system("cls");
}
}
int main()
{
test();
return 0;
}
文件版本的通讯录到此为止。🤞