【C语言】通讯录《信息写到文件版本》
创始人
2024-04-26 04:23:18
0

🚩write in front🚩   

🔎大家好,我是謓泽,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎
🏅2021年度博客之星物联网与嵌入式开发TOP5~2021博客之星Top100~阿里云专家博主 & 星级博主~掘金⇿InfoQ~51CTO创作者[新人榜No.7]~周榜257﹣总榜931⇿全网访问量40w+🏅
🆔本文由 謓泽 原创 CSDN首发🙉如需转载还请通知⚠

📺创作时间 ↔ 2021年3月18日◬
📝个人主页-謓泽的博客_CSDN博客 📃
🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​
📣系列专栏-YY_謓泽的博客-CSDN博客🎓
✉️我们并非登上我们所选择的舞台,演出并非我们所选择的剧本📩

目录

🚩write in front🚩   

概述 

增添の功能

Save_Contact() → 保存通讯录信息

读文件操作 

模块化代码实现 

Ⅰ→  test.c

Ⅱ→address_book.h

Ⅲ→address_book.c

✨最后✨

概述 

这个是在之前的动态版本进行添加,如果你不清楚通讯录的静态或者是动态怎么实现。可以看看博主写的前面两篇通讯录的静态和动态的实现↓

🍖链接→🍖【C语言】通讯录《静态内存版本》_謓泽的博客-CSDN博客

🍗链接→🍗【C语言】通讯录《动态内存版本》_謓泽的博客-CSDN博客


增添の功能

相比之前的静态版本还是动态版本。这个信息写到文件版本,无疑是更加完善的。如果你不会文件操作的话,可以看看我前面写过的内存的一篇博客来看看⇣

链接→【C语言】内存函数_謓泽的博客-CSDN博客

增添の功能↓

(1)→当通讯录退出的时候,把信息写到文件里面。

(2)→当通讯录初始化的时候,加载文件的信息到通讯录当中去。

在上述的博客当中我们是↓

Destory_Contact(&con);//销毁通讯录

而在这篇博客我们实现的是首先要保存通讯录,也就是保存信息到文件去。那么我们创建一个函数实现保存信息到文件里。

Save_Contact(&con);//保存信息到文件

Save_Contact() → 保存通讯录信息

那么首先我们要实现这个保存通讯录信息到文件的这个函数。

Save_Contact() 代码示例如下↓

//读写信息到文件
void Save_Contact(Contact* pc)
{FILE* pf = fopen("information.txt","w");//返回值判断if (pf == NULL){perror("Save_Contact:");return;}//写文件int i = 0;for (i = 0; i < pc->sz; i++){//数组名+i就是数组名下标元素的地址。fwrite(pc->date + i, sizeof(information), 1, pf);}//关闭文件fclose(pf);pf = NULL;
}

那么现在我们就可以试一下,那我们就把张三同学的通讯录信息写下。

张三:?????????????,算了为了张三同学的隐私我们就不这样了(o゚v゚)ノ

直接简单一点打印输入数字①来康康吧。

从上述的截屏当中可以知道我们是写入进去东西的。


读文件操作 

现在我们保存文件是没有任何的问题了,但是当我们再次运行通讯录的时候。通讯录依然会什么都会没有。所以,此时我们就需要进行读文件的一个操作。

我们在初始化的时候就可以进行读文件的一个操作了,因为在此之前已经有增删查改了。

那我们封装一个函数用read_file()来进行实现。 

void read_file(Contact* pc)
{FILE* pf = fopen("information.txt", "r");//返回值判断if (pf == NULL){perror("read_file");return;}//读文件information tmp = {0};//问题:读文件停止(不知道你写入几个信息)?返回值的问题实际countwhile (fread(&tmp, sizeof(information), 1, pf))//读不到返回0{//是否增容Cap_inc(pc);//存放增容元素pc->date[pc->sz] = tmp;//加载信息pc->sz++;}//关闭文件fclose(pf);pf = NULL;
}

让我们来看看是否能进行一个读文件的操作。检测是非常简单的,我们先输入一个张三,再退出程序。然后,再输入一个李四。看看能不能读写上次张三的信息。

输入界面数字:6 即可(o゚v゚)ノ

第一次的输入! 

上述的读写操作是成功的。 

第二次的输入!

从这里我们可以知道它保存了我们上述的读写的值,也就是读文件的操作我们是成功的了。


模块化代码实现 

Ⅰ→  test.c

代码示例如下↓

/*@Note1:当通讯录退出的时候,把信息写道文件。@Note2:当通讯录初始化的时候,加载文件的信息。
*/
#define _CRT_SECURE_NO_WARNINGS 1
#include"a.h"
#include
#pragma warning(disable:6031)
//颜色函数
void color(short x)
{if (x >= 0 && x <= 15)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), x);elseSetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
}
//创建菜单函数
void menu()
{color(0);//黑色system("cls");//清屏color(12);//白色printf("¤--------------------------------------------¤\n");printf("|■■■■■■■■→通讯录v1.0←■■■■■■■■|\n");printf("|———————————————————————|\n");printf("|★★★★★→1.increase ■ 2.deLete←★★★★★|\n");printf("|★★★★★→3.find     ■ 4.Revise←★★★★★|\n");printf("|★★★★★→5.Check    ■ 6.Print ←★★★★★|\n");printf("|★★★★★→0.Exit     ■         ←★★★★★|\n");printf("|———————————————————————|\n");printf("|■■■■■■■■→通讯录v1.0←■■■■■■■■|\n");printf("¤--------------------------------------------¤\n");
}
enum Number
{Exit,Increase,DeLete,Find,Revise,Check,Print,
};
int main(void)
{menu();int input = 0;//当然初始化全0:Contact con = {0};也是可以的,当然我们这里的初始化不是这样的原因是可以应对比较复杂的问题。Contact con;//初始化通讯录//给date申请一块连续的内存空间存放在堆区上。InitContact(&con);do{color(5);printf("¤----------------¤\n");printf("|请输入界面上的数字|:");scanf("%d", &input);printf("¤----------------¤\n");color(1);switch (input){case Exit://销毁之前先保存。Save_Contact(&con);//把通讯录里面的内存空间date给释放掉。Destory_Contact(&con);//销毁通讯录。printf("══════════════@\n");printf("退出通讯录v1.0@\n");printf("══════════════@\n");break;case Increase://增加人的信息,放在通讯录当中去。Add_Contact(&con);break;case DeLete://删除通讯人的信息DeLete_Contact(&con);break;case Find://查找指定通讯录人的信息Find_Contact(&con);break;case Revise://修改指定通讯录人的信息Revise_Contact(&con);break;case Check://排查通讯录当中人员的信息Check_Contact(&con);break;case Print://打印通讯录当中人员的信息。Print_Contact(&con);break;default:printf("你输入的数字找不到,请重新输入~\n");}} while (input);return 0;
}

Ⅱ→address_book.h

#define _CRT_SECURE_NO_WARNINGS 1
#include 
#include
#include
#include#define Max_name 5
#define Max_age 100
#define Max_genger 3
#define Max_address 20
#define Max_telephone 20//#define num 1000 //静态的存放
#define Defsz 3 //一开始的值
#define Inc 2  //每次的增量//类型的定义
typedef struct information
{//名字、年龄、性别、电话、地址。char name[Max_name];char age[Max_age];char genger[Max_genger];char telephone[Max_telephone];char address[Max_address];
}information;//通讯录 - 动态版本
typedef struct Contact
{//这里用了个结构体嵌套information* date;//指向动态内存的申请空间,用于存放联系人的信息。int sz;//记录当前通讯录有效信息的个数。int capacity;//表示当前通讯录的最大"容量"大小。
}Contact;//初始化通讯录
void InitContact(Contact* pc);
//增加通讯录信息
void Add_Contact(Contact* pc);
//打印通讯录的信息
void Print_Contact(const Contact* pc);
//删除通讯人的信息
void DeLete_Contact(Contact* pc);
//查找指定通讯录人的信息
void Find_Contact(Contact* pc);
//修改指定通讯录人的信息
void Revise_Contact(Contact* pc);
//排查通讯录当中人员的信息
void Check_Contact(Contact* pc);
//销毁通讯录
void Destory_Contact(Contact* pc);//保存通讯录信息到文件
void Save_Contact(Contact* pc);//读文件-加载文件
void read_file(Contact* pc);//检测增容
void Cap_inc(Contact* pc);

Ⅲ→address_book.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"address_book.h"//读文件-加载文件
void read_file(Contact* pc)
{FILE* pf = fopen("information.txt", "r");//返回值判断if (pf == NULL){perror("read_file");return;}//读文件information tmp = {0};//问题:读文件停止(不知道你写入几个信息)?返回值的问题实际countwhile (fread(&tmp, sizeof(information), 1, pf))//读不到返回0{//是否增容Cap_inc(pc);//存放增容元素pc->date[pc->sz] = tmp;//加载信息pc->sz++;}//关闭文件fclose(pf);pf = NULL;
}//动态版本进行初始化
void InitContact(Contact* pc)
{pc->date = (information*)malloc(Defsz * sizeof(information));if (pc->date == NULL){perror("InitContact");return;}//如果返回的为空指针的情况pc->sz = 0;//sz初始化pc->capacity = Defsz;//当前最大"容量"//读文件-加载文件read_file(pc);
}//增容函数
void Cap_inc(Contact* pc)
{//当记录当前通讯录有效信息的个数 等于 表示当前通讯录的最大"容量"大小。if (pc->sz == pc->capacity){//给堆区增加"容量",因为空间不够。information* pa = (information*)realloc(pc->date, (pc->capacity + Inc)*(sizeof(information)));if (pa != NULL){pc->date = pa;//把这块空间移交到date进行维护pc->capacity = pc->capacity + Inc;//由于这里我们进行了增容也需要把容量改变成+Inc的值printf("增加联系人已成功(@^0^)\n");}//增容失败else{perror("Add_Contact:");printf("增加联系人失败!(ToT)/~~~\n");return;}}
}//动态版本增加
void Add_Contact(Contact* pc)
{//检测容量Cap_inc(pc);//增加一个人的信息printf("\n");printf("请输入增加人的名字->:");scanf("%s", pc->date[pc->sz].name);//注意→数组名是首元素地址,所以不用进行取地址.printf("请输入增加人的年龄->:");scanf("%s", pc->date[pc->sz].age);printf("请输入增加人的性别->:");scanf("%s", pc->date[pc->sz].genger);printf("请输入增加人的电话->:");scanf("%s", pc->date[pc->sz].telephone);printf("请输入增加人的地址->:");scanf("%s", pc->date[pc->sz].address);//成功~pc->sz++;printf("★恭喜你~添加信息成功★\n");printf("\n");
}//读写信息到文件
void Save_Contact(Contact* pc)
{FILE* pf = fopen("information.txt","w");//返回值判断if (pf == NULL){perror("Save_Contact:");return;}//写文件int i = 0;for (i = 0; i < pc->sz; i++){//数组名+i就是数组名下标元素的地址。fwrite(pc->date + i, sizeof(information), 1, pf);}//关闭文件fclose(pf);pf = NULL;
}void Print_Contact(const Contact* pc)
{int i = 0;//打印标题栏的信息printf("|-------------------------------------------------------|\n");printf("|%-3s\t%-3s\t%-3s\t%-11s\t%-10s\t|\n", "名字", "年龄", "性别", "电话", "地址");for (i = 0; i < pc->sz; i++){printf("|%-3s\t%-3s\t%-3s\t%-11s\t%-10s\t|\n", pc->date[i].name,pc->date[i].age,pc->date[i].genger,pc->date[i].telephone,pc->date[i].address);}
}static int FindByname(Contact* pc, char name[])
{int i = 0;//用for循环进行遍历for (i = 0; i < pc->sz; i++){//strcmp()比较字符串if (strcmp(pc->date[i].name, name) == 0){return i;//返回下标}}return -1;
}void DeLete_Contact(Contact* pc)
{char name[Max_name] = { 0 };//通讯录为空的时候if (pc->sz == 0){printf("通讯录当中没有任何信息\n");return;}printf("请输入你要删除的名字->:");scanf("%s", name);//查找要删除的人:有/没有int ret = FindByname(pc, name);if (ret == -1){printf("没有查找到当前人的信息\n");return;}//删除int i = 0;for (i = ret; i < pc->sz - 1; i++){pc->date[i] = pc->date[i + 1];}pc->sz--;//因为我们删除成功下标要减1printf("★恭喜你~删除信息成功★\n");printf("\n");
}void Find_Contact(Contact* pc)
{char name[Max_name] = { 0 };printf("请输入你要查找的名字->:");scanf("%s", name);int ret = FindByname(pc, name);if (ret == -1){printf("没有查找到当前人的名字\n");return;}else{printf("|-------------------------------------------------------|\n");printf("|%-3s\t%-3s\t%-3s\t%-11s\t%-10s\t|\n", "名字", "年龄", "性别", "电话", "地址");printf("|%-3s\t%-3s\t%-3s\t%-11s\t%-10s\t|\n", pc->date[ret].name,pc->date[ret].age,pc->date[ret].genger,pc->date[ret].telephone,pc->date[ret].address);printf("查找%sの信息成功~\n", pc->date[ret].name);}
}void Revise_Contact(Contact* pc)
{char name[Max_name] = { 0 };printf("请输入你要修改通讯录人的名字->:");scanf("%s", name);int ret = FindByname(pc, name);if (ret == -1){printf("当前修改人的信息不存在\n");return;}else{printf("请输入修改人的名字->:");scanf("%s", pc->date[ret].name);//注意→数组名是首元素地址,所以不用进行取地址.printf("请输入修改人的年龄->:");scanf("%s", pc->date[ret].age);printf("请输入修改人的性别->:");scanf("%s", pc->date[ret].genger);printf("请输入修改人的电话->:");scanf("%s", pc->date[ret].telephone);printf("请输入修改人的地址->:");scanf("%s", pc->date[ret].address);printf("恭喜你,修改成功~\n");}
}int sort_name_max(const void* e1, const void* e2)
{return (strcmp(((struct Contact*)e1)->date->name, ((struct Contact*)e2)->date->name));
}void Check_Contact(Contact* pc)
{//qosrt()函数首字母进行排序qsort(pc->date, pc->sz, sizeof(pc->date[0]), sort_name_max);printf("|-------------------------------------------------------|\n");printf("|%-3s\t%-3s\t%-3s\t%-11s\t%-10s\t|\n", "名字", "年龄", "性别", "电话", "地址");int i = 0;for (i = 0; i < pc->sz; i++){printf("|%-3s\t%-3s\t%-3s\t%-11s\t%-10s\t|\n", pc->date[i].name,pc->date[i].age,pc->date[i].genger,pc->date[i].telephone,pc->date[i].address);}
}void Destory_Contact(Contact* pc)
{//销毁通讯录实际上就是把date给释放掉,free()函数进行回收即可。free(pc -> date);pc->date = NULL;pc->sz = 0;pc->capacity = 0;//记得清0☆⌒(*^-゜)v THX!!
}

✨最后✨

那么这个就已经实现了通讯录的最终版本了,这个项目适合已经把C语言学完的人做。巩固自己以往的能力,做个这个提升自己逻辑思维和代码能力的一个小的项目。

记得三连^o^y

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
客厅放八骏马摆件可以吗(家里摆... 今天给各位分享客厅放八骏马摆件可以吗的知识,其中也会对家里摆八骏马摆件好吗进行解释,如果能碰巧解决你...
苏州离哪个飞机场近(苏州离哪个... 本篇文章极速百科小编给大家谈谈苏州离哪个飞机场近,以及苏州离哪个飞机场近点对应的知识点,希望对各位有...