通讯录【三】文件版本
作者:日出等日落
专栏:C语言
幸福存在于生活之中,而生活存在于劳动之中。 ——列夫·托尔斯泰
目录
概况
完整代码展示:
Contact.h 结构体和函数的声明,以及头文件的引用
Contact.c 通讯录各种功能函数的实现
text.c 通讯录的菜单以及主函数
概况
大家好,之前发布了两个版本的通讯录,一个是静态通讯录的版本,一个是动态通讯录;这两个版本每次打开的时候都要重新输入,而不能保存起来,所以就很麻烦,
那么现在我将给大家讲解一下将通讯录用文件的方式保存起来。(如需了解动态内存函数,请看http://t.csdn.cn/XnRLr)
需求:
- 通讯录退出之后,之前保存的信息不能丢,当下次重新运行通讯录的时候,还能看到上次保存的信息。
分析:
- 退出 的时候,把数据保存到文件中,当下一次运行的时候,再从文件中加载信息就可以了。
其中主要包含了六大块内容:
- 联系人的添加
- 联系人的删除
- 联系人的查找
- 联系人的修改
- 联系人的展示
- 联系人的排序
- 销毁通讯录中的联系人
- 保存通讯录(新增)
- 加载文件信息到通讯录中(新增)
完整代码展示:
首先,我将通讯录分成了三个部分:
1、text.c //通讯录的菜单以及主函数
2、Contact.h //结构体和函数的声明,以及头文件的引用
3、Contact.c //通讯录各种功能函数的实现
Contact.h 结构体和函数的声明,以及头文件的引用
#pragma once
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_TELE 20
#define MAX_ADDR 30
#define MAX 100//通讯录默认大小
#define CAPACITY 3
//空间满后,每次增加2个信息
#define INF 2//表示一个人的信息
struct PeoInfo
{char name[MAX_NAME];char sex[MAX_SEX];char tele[MAX_TELE];int age;char addr[MAX_ADDR]; //住址
};
//静态的版本
//struct Contact
//{
// struct PeoInfo data[100];
// int sz ;//表示通讯录中还没有信息
//
//};
// struct Contact
{struct PeoInfo *data;int sz;//已经放进去的信息int capacity;//容量};//初始化通讯录
void InitContact(struct Contact* pc);//给通讯录添加联系人
void AddContact(struct Contact* pc);//显示通讯录的信息
void ShowContact(const struct Contact* pc);//删除指定联系人
void DelContact(struct Contact* pc);//查找指定联系人
void SearchContact(const struct Contact* pc);//修改指定联系人
void ModifyContact(struct Contact* pc);//排序通讯录
void SortContact(struct Contact* pc);//销毁通讯录
void DestoryContact(struct Contact* pc);//保存通讯录
void SaveContact(struct Contact* pc);//加载文件信息到通讯录中
void LoadContact(struct Contact* pc);
Contact.c 通讯录各种功能函数的实现
#define _CRT_SECURE_NO_WARNINGS 1
#include"Contact.h"//静态版本
//void InitContact(struct Contact* pc)
//{
// assert(pc);//防止pc是空指针
// pc->sz = 0;
// memset(pc->data, 0, 100 * sizeof(struct PeoInfo));//将pc->里面的100数据的字节数全部赋为0
//}static int check_capacity(struct Contact* pc);void LoadContact(struct Contact* pc)
{
//打开文件FILE* pf=fopen("Contact.txt", "rb");if (pf == NULL){perror(" LoadContact");return;}//读文件struct PeoInfo tmp = { 0 };while (fread(&tmp, sizeof(struct PeoInfo), 1, pf)){//考虑增加容量的问题check_capacity(pc);pc->data[pc->sz] = tmp;pc->sz++;}//关闭文件fclose(pf);pf = NULL;}void InitContact(struct Contact* pc)
{assert(pc);//防止pc是空指针pc->data = (struct PeoInfo*) malloc(CAPACITY *sizeof(struct PeoInfo));if (pc->data == NULL){perror("InitContact()");return;}pc->sz = 0;pc->capacity = CAPACITY;//加载文件中的信息到通讯录中LoadContact(pc);
}void DestoryContact(struct Contact* pc)
{free(pc->data);pc->data = NULL;pc->capacity=0;pc->sz = 0;
}//静态版本
//void AddContact(struct Contact* pc)
//{
// if (pc->sz == MAX)
// {
// printf("通讯录已满,无法添加数据\n");
// 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].tele);
// printf("请输入住址:>");
// scanf("%s", pc->data[pc->sz].addr);
// pc->sz++;
// printf("成功添加联系人\n");
//}
static int check_capacity(struct Contact *pc)
{if (pc->sz == pc->capacity){//增加容量struct PeoInfo* ptr = (struct PeoInfo*)realloc(pc->data, (pc->capacity + INF) * sizeof(struct PeoInfo));if (ptr != NULL){pc->data = ptr;pc->capacity += INF;printf("增容成功\n");return 1;}else{perror("AddContact()");return 0;}}elsereturn 1;
}//动态增长的版本
void AddContact(struct Contact* pc)
{assert (pc);if (0 == check_capacity(pc)){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].tele);printf("请输入住址:>");scanf("%s", pc->data[pc->sz].addr);pc->sz++;printf("成功添加联系人\n");
}void ShowContact(struct Contact* pc)
{int i = 0;printf("%-20s\t%-5s\t%-5s\t%-20s\t%-30s\n", "姓名", "性别", "年龄", "电话", "地址");for (i = 0; i < pc->sz; i++){printf("%-20s\t%-5s\t%-5d\t%-20s\t%-30s\n", pc->data[i].name,pc->data[i].sex,pc->data[i].age,pc->data[i].tele,pc->data[i].addr); }
}//这里的static表示该函数只能在所在的源文件中使用,其他文件不能使用
static int FindByName(const struct Contact* pc, char name[])
{int i = 0;for (i = 0; i < pc->sz; i++){if (0 == strcmp(pc->data[i].name, name)){return i;}}return -1;
}
void DelContact(struct Contact* pc)
{char name[MAX_NAME];printf("请输入你想要删除人的姓名:>");scanf("%s", name);int ret = FindByName(pc, name);if (ret == -1){printf("要删除的人不存在\n");}else{//删除int j = 0;for (j = ret; j < pc->sz - 1; j++){pc->data[j] = pc->data[j + 1];}pc->sz--;printf("成功删除指定联系人\n");}
}void SearchContact(const struct Contact* pc)
{char name[MAX_NAME];printf("请输入你想要查找人的姓名:>");scanf("%s", name);//查找一下指定联系人是否存在int ret = FindByName(pc, name);if (ret == -1){printf("要查找的人不存在\n");}else{printf("%-20s\t%-5s\t%-5s\t%-20s\t%-30s\n", "姓名", "性别", "年龄", "电话", "地址");printf("%-20s\t%-5s\t%-5d\t%-20s\t%-30s\n", pc->data[ret].name,pc->data[ret].sex,pc->data[ret].age,pc->data[ret].tele,pc->data[ret].addr);}
}void ModifyContact(struct Contact* pc)
{printf("请输入想要修改人的名字:>");char name[MAX_NAME];scanf ("%s", name);int ret = FindByName(pc, name);if (ret == -1){printf("要修改的联系人不存在\n");}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].tele);printf("请输入住址:>");scanf("%s", pc->data[ret].addr);printf("修改成功\n");}
}//按照年龄来排序
//int CmpByAge(const void* e1, void* e2)
//{
// return ((struct PeoInfo*)e1)->age - ((struct PeoInfo*)e2)->age;
//}//按照名字排序
int CmpByName(const void* e1, void* e2)
{return strcmp(((struct PeoInfo*)e1)->name , ((struct PeoInfo*)e2)->name);
}void SortContact(struct Contact* pc)
{qsort(pc->data, pc->sz, sizeof(struct PeoInfo), CmpByName);
}void SaveContact(struct Contact* pc)
{
//打开文件//wb是二进制的写FILE* pfW = fopen("Contact.txt", "wb");if (pfW == NULL){perror("fopen");return ;}//写文件int i = 0;for (i = 0; i < pc->sz; i++){fwrite(pc->data + i, sizeof(struct PeoInfo), 1, pfW);}//关闭文件fclose(pfW);pfW = NULL;}
text.c 通讯录的菜单以及主函数
#define _CRT_SECURE_NO_WARNINGS 1
#include "Contact.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");}enum Option
{EXIT,ADD,DEL,SEARCH,MODIFY,SHOW,SORT
};
int main()
{int input = 0;//创建通讯录struct Contact con;//存放通讯录数据//初始化通讯录InitContact(&con);do{menu();printf("请选择>:");scanf("%d", &input);switch(input){case ADD:AddContact(&con);break;case DEL:DelContact(&con);break;case SEARCH:SearchContact(&con);break;case MODIFY:ModifyContact(&con);break;case SHOW:ShowContact(&con); break;case SORT:SortContact(&con);break;case EXIT:SaveContact(&con);printf("保存文件成功\n");DestoryContact(&con);printf("退出通讯录\n");break;default:printf("选择错误,请重新输入\n");break;}} while (input);return 0;
}
其中关于文件相关的知识,请参考:http://t.csdn.cn/JhzrN
欢迎大佬们指点!!!!!
通讯录【三】文件版本相关推荐
- 通讯录的实现(静态版本,动态版本,文件版本)(后附完整源代码)
通讯录的实现 一.静态版本 1.所需要的功能 2.大致菜单 3.创建通讯录 4.增加联系人 5.显示联系人 6.查找联系人 7.删除联系人 8.修改联系人 9.按名字排序 10.源代码 二.动态版本 ...
- 从0开始学c语言 - 34 - 通讯录 -静态、动态、存到文件(三种版本)
上一篇:从0开始学c语言-33-动态内存管理_阿秋的阿秋不是阿秋的博客-CSDN博客 我发现,理论的学习文章没几个人看,如果是这种实践类型的文章,看的人很多,偏偏我之前都是扔完代码就走了,也没认真写这 ...
- C语言文件操作+通讯录实现文件操作
文章目录 前言 一.为什么使用文件 二.什么是文件 三.文件的打开和关闭 四.文件的顺序读写 五.文件的随机读写 六.文本文件和二进制文件 七.文件读取结束的判定 八.文件缓冲区 前言 电脑文件,也可 ...
- 【C语言】通讯录(文件版)
这里写目录标题 一.通讯录说明 二.效果展示 三.代码展示 一.通讯录说明 通讯录拥有增.删.查.改等功能. 本文主要介绍通讯录文件版本,以动态版本的方式开辟空间. 文件版本功能:通讯录退出后,之前保 ...
- (原创)一个JavaScript Function Outliner插件 第三个版本 让你的JavaScript代码也支持折叠...
今天我为大家带来JavaScript Function Outliner插件的第三个版本,在这个版本里我们也可以对JavaScript的代码进行折叠了 不过目前支持折叠的就function 发布前两个 ...
- 【Android 逆向】ELF 文件格式 ( ELF 文件类型 | ELF 文件对应 CPU 架构 | ELF 目标文件版本 | 可执行程序起始地址 )
文章目录 一.ELF 文件类型 ( 动态库文件 ) 二.ELF 文件对应 CPU 架构 三.ELF 目标文件版本 四.可执行程序起始地址 一.ELF 文件类型 ( 动态库文件 ) ELF 文件头 第 ...
- Ubuntu 10.10, 11.04, 11.10这三个版本无法从优盘启动
问题:Ubuntu 10.10, 11.04, 11.10这三个版本无法从优盘启动 解决:从U盘启动安装的时候,会卡住不动. 搞定办法相当简单,修改syslinux/syslinuxfg文件: 将de ...
- 使用git管理文件版本(本地仓库)
目标:使用git在本地仓库完成版本控制,及相关命令的使用. 创建版本库 添加文件 修改文件 删除文件 删除文件并保存副本 将java工程提交到版本库 忽略文件(提交版本库时,可忽略某些文件) 1,创建 ...
- 数字IC入门工具大全之 英特尔 Quartus Prime是什么?三个版本有什么区别
Intel Quartus Prime是Intel出品的可编程逻辑器件设计软件:在英特尔收购 Altera 之前,该工具被称为Altera Quartus Prime,更早的Altera Quartu ...
- 怎么查看CAD文件信息和文件版本?
CAD文件是我们工作当中经常会使用到的文件,如果我们拿到一个新的CAD文件时,想要对新的CAD文件信息和文件版本进行查看,那么我们应该如何操作?怎么查看CAD文件信息和文件版本?接下来小编就告诉大家具 ...
最新文章
- CentOS修改忘记密码
- WordPress 5.2 Beta 3 发布,要求 PHP 5.6.20 以上版本
- win7系统0xt000000f错误代码的解决方法
- 单片机c语言计数器测速,基于51单片机的光电编码器测速.doc
- JSP中URL路径获取问题
- struts2、ajax实现前后端交互
- 剑指Offer之寻找数据流中的中位数【包含大顶堆小顶堆解释】
- Flutter实战一Flutter聊天应用(十九)
- redhat6.3下安装ORACLE11.2.3RAC
- 如何找到最快的DNS服务器!!
- authorware学习
- PMP新考纲启用,如何判断是敏捷?第6版教材与第7版有什么区别?
- 深信服技术认证之Openstack云平台使用入门
- 三调数据库标注插件v1.2
- matlab 滤波器设计工具,滤波器设计工具快速入门
- codewars 7×7 Skyscrapers 问题解决
- Python进阶之路(2):批量下载豆瓣FM红心音乐MP3到本地
- Python编程的一些实例(1)
- 强化学习待解决问题和主流Trick整理
- ksweb如何安装php5.6_KSWEB - server + PHP + MySQL