C语言之通讯录的制作并用文件存储
前言:
通过c语言来模拟一个通讯录的实现,来储存1000个联系人的信息,并保存在文件中
每个个人信息包括:
姓名,性别,电话,地址
功能包括:
联系人的添加
联系人的删除
联系人的查找
联系人的修改
- 结构体的定义
typedef struct list{char name[10];char sex[10];char phone[20];char address[30];int n;
}List;
结构体的成员皆为字符型,因为这样在我们储存通讯录的.txt文档中就可以直接查看所有的通讯录成员的内容。
- 菜单
一个通讯录的实现离不开菜单,菜单的主要作用是将各个功能联系在一起,使使用者根据自己的要求,使用通讯录。
void menu(){int n;do{printf("*********************************\n");printf("** 1. 添加联系人 **\n");printf("** 2. 删除联系人 **\n");printf("** 3. 查找联系人 **\n");printf("** 4. 修改联系人 **\n");printf("** 0. 退出 **\n");printf("*********************************\n");scanf("%d",&n);if(n == 1){add();}else if(n == 2){del();}else if(n == 3){seek();}else if(n == 4){modify();}}while(n != 0);
}
通过输入n值进行功能的选择,用do while 结构,让使用者在进行一个功能的完整实现后,能够回到菜单进行下一个功能的选择,直到n == 0 时,退出菜单。
- 功能模块的实现
全局变量和宏定义
#define NUM 1000//用来设置最大存储量
int now = 0;//用来标识当前存储的数量
(1)添加联系人
void add(){char cn;do{if(now == NUM){printf("通讯录已满\n");}else{printf("请输入姓名\n");scanf("%s",&a[now].name);printf("请输入性别\n");scanf("%s",&a[now].sex);printf("请输入电话\n");scanf("%s",&a[now].phone);printf("请输入地址\n");scanf("%s",&a[now].address);now++;}printf("如果你想继续添加联系人请按y\n");printf("或者按任意键退出\n");getchar();scanf("%c",&cn);}while(cn == 'y');
}
注:scanf前面要有getchar,用来读走回车符
(2)删除联系人
void del(){char cn;do{printf("如果你想删除所有联系人请按1\n");printf("如果你想删除单个联系人请按2\n");int n;scanf("%d",&n);if(n == 1){init();//自定义的初始化函数now =0;}else if(n == 2){printf("请输入要删除联系人的姓名\n");char b[10];int f = 0;scanf("%s",b);for(int i =0;i<now;i++){if(strcmp(b,a[i].name) == 0){f++;memset(&a[i],0,sizeof(List));if(i < now-1){//判断删除的联系人是否是最后一个while(i<now-1){//将后一个联系人向前移一个,填补空缺strcpy(a[i].name,a[i+1].name);strcpy(a[i].sex ,a[i+1].sex);strcpy(a[i].phone,a[i+1].phone);strcpy(a[i].address,a[i+1].address);memset(&a[i+1],0,sizeof(List));//将后一个联系人删掉i++;}}now--;break;}}if(f == 0){printf("未找到该联系人\n");}printf("如果你想继续删除联系人请按y\n");printf("或者按任意键退出\n");getchar();scanf("%c",&cn);}}while(cn == 'y');
}
大致流程与add函数差不多,主要是该函数有两个选项,一个为清空通讯录,一个为清除单个联系人。
同时在删除单个联系人的时候要进一步判断是否删除的是最后一个联系人,如果不是则还需要将选中要删除联系人后面的联系人往前移。
(3)查找联系人
void seek (){char cn;do{printf("请输入你所要查找的内容(姓名\\性别\\电话\\地址)\n");char b[30];scanf("%s",b);int i,f = 0;char *p[4];//指针数组,每个数组元素可以看成一个指针for(i =0;i<now;i++){p[0] = strstr(a[i].name,b);p[1] = strstr(a[i].sex,b);p[2] = strstr(a[i].phone,b);p[3] = strstr(a[i].address,b);//strstr用来查找子集的,比如说123,你输入12,12为123的子集,就会返回一个指针//否则返回一个空指针if(p[0] !=NULL ||p[1] != NULL||p[2] != NULL||p[3] != NULL){f++;printf("第%d个\n姓名:%s\n性别:%s\n电话:%s\n地址:%s\n",f,a[i].name,a[i].sex,a[i].phone, a[i].address);}}if(f==0){printf("未查到相应内容\n");}printf("如果你想继续查找联系人请按y\n");printf("或者按任意键退出\n");getchar();scanf("%c",&cn);}while(cn == 'y');
}
该部分使用了<string.h>中的strstr函数,具体用法可以进行百度,大致是寻找元素的子集,如:一个联系人叫张三,但你不知到他姓什么,只知道有个三,你就可以通过三来寻找张三。
(4)修改联系人
void modify (){char cn;do{printf("请输入要修改的联系人姓名\n");char b[10];int f = 0;scanf("%s",b);for(int i=0;i<now;i++){if(strcmp(b,a[i].name) == 0){f++;printf("修改后的姓名\n");scanf("%s",&a[i].name);printf("修改后的性别\n");scanf("%s",&a[i].sex);printf("修改后的电话\n");scanf("%s",&a[i].phone);printf("修改后的地址\n");scanf("%s",&a[i].address);break;}}if(f == 0){printf("未找到该联系人");}printf("如果你想继续修改联系人请按y\n");printf("或者按任意键退出\n");getchar();scanf("%c",&cn);}while(cn == 'y');
}
该部分较简单,用strcmp寻找要修改的联系人的名字,然后进行修改就行。
- 文件的读取和写入
(1)文件读取
void copy(){init();FILE *pf;if((pf = fopen("list.txt","r")) ==NULL){printf("通讯录打开失败\n");exit(1);}else{int n,i=0;do{n = fread(&a[i++],sizeof(List),1,pf);}while(n == 1);now = i-1;}fclose(pf);
}
void init (){memset(a,0,sizeof(List)*NUM);
}
文件的读取要放在整个程序的开头,因为程序主体部分是通过修改结构体数组中的内容实现的,并不是直接在文件中进行操作,因此要先将通讯录已有的成员读取到结构体数组中,再对结构体数组进行操作。
注:要事先再对应的文件夹中设置list.txt文件储存通讯录的内容,因为“r”是打开已有的文件。
(2)文件的写入
void file (){FILE *f;if( ( f = fopen("list.txt","w")) == NULL){printf("打开失败\n");exit(-1);}else{int i = 0;while(i<now){fwrite(&a[i],sizeof(List),1,f);i++;}}fclose(f);
}
文件的写入放到整个程序的后面,当使用者完成所有的功能,结构体数组的内容不会再发生变化时,便可以将结构体数组写入程序,“w”打开,可以理解为更新文件,新的文件会覆盖旧的文件,以实现文件内容的修改。
- 完整代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define NUM 1000 //通讯录最大容量
typedef struct list{char name[10];char sex[10];char phone[20];char address[30];
}List;
List a[NUM];//结构体数组
int now = 0;//用来标记一共有多少个联系人
void init ();
void copy();
void menu();
void add();
void seek();
void del();
void modify();
void file();
void init (){memset(a,0,sizeof(List)*NUM);
}
void copy(){init();FILE *pf;if((pf = fopen("list.txt","r")) ==NULL){printf("通讯录打开失败\n");exit(1);}else{int n,i=0;do{n = fread(&a[i++],sizeof(List),1,pf);}while(n == 1);now = i-1;}fclose(pf);
}
void menu(){int n;do{printf("*********************************\n");printf("** 1. 添加联系人 **\n");printf("** 2. 删除联系人 **\n");printf("** 3. 查找联系人 **\n");printf("** 4. 修改联系人 **\n");printf("** 0. 退出 **\n");printf("*********************************\n");scanf("%d",&n);if(n == 1){add();}else if(n == 2){del();}else if(n == 3){seek();}else if(n == 4){modify();}}while(n != 0);
}
void add(){char cn;do{if(now == NUM){printf("通讯录已满\n");}else{printf("请输入姓名\n");scanf("%s",&a[now].name);printf("请输入性别\n");scanf("%s",&a[now].sex);printf("请输入电话\n");scanf("%s",&a[now].phone);printf("请输入地址\n");scanf("%s",&a[now].address);now++;}printf("如果你想继续添加联系人请按y\n");printf("或者按任意键退出\n");getchar();scanf("%c",&cn);}while(cn == 'y');
}
void del(){char cn;do{printf("如果你想删除所有联系人请按1\n");printf("如果你想删除单个联系人请按2\n");int n;scanf("%d",&n);if(n == 1){init();now =0;}else if(n == 2){printf("请输入要删除联系人的姓名\n");char b[10];int f = 0;scanf("%s",b);for(int i =0;i<now;i++){if(strcmp(b,a[i].name) == 0){f++;memset(&a[i],0,sizeof(List));if(i < now-1){//判断删除的联系人是否是最后一个while(i<now-1){//将后一个联系人向前移一个,填补空缺strcpy(a[i].name,a[i+1].name);strcpy(a[i].sex ,a[i+1].sex);strcpy(a[i].phone,a[i+1].phone);strcpy(a[i].address,a[i+1].address);memset(&a[i+1],0,sizeof(List));//将后一个联系人删掉i++;}}now--;break;}}if(f == 0){printf("未找到该联系人\n");}printf("如果你想继续删除联系人请按y\n");printf("或者按任意键退出\n");getchar();scanf("%c",&cn);}}while(cn == 'y');
}
void seek (){char cn;do{printf("请输入你所要查找的内容(姓名\\性别\\电话\\地址)\n");char b[30];scanf("%s",b);int i,f = 0;char *p[4];//指针数组,每个数组元素可以看成一个指针for(i =0;i<now;i++){p[0] = strstr(a[i].name,b);p[1] = strstr(a[i].sex,b);p[2] = strstr(a[i].phone,b);p[3] = strstr(a[i].address,b);//strstr用来查找子集的,比如说123,你输入12,12为123的子集,就会返回一个指针//否则返回一个空指针if(p[0] !=NULL ||p[1] != NULL||p[2] != NULL||p[3] != NULL){f++;printf("第%d个\n姓名:%s\n性别:%s\n电话:%s\n地址:%s\n",f,a[i].name,a[i].sex,a[i].phone, a[i].address);}}if(f==0){printf("未查到相应内容\n");}printf("如果你想继续查找联系人请按y\n");printf("或者按任意键退出\n");getchar();scanf("%c",&cn);}while(cn == 'y');
}
void modify (){char cn;do{printf("请输入要修改的联系人姓名\n");char b[10];int f = 0;scanf("%s",b);for(int i=0;i<now;i++){if(strcmp(b,a[i].name) == 0){f++;printf("修改后的姓名\n");scanf("%s",&a[i].name);printf("修改后的性别\n");scanf("%s",&a[i].sex);printf("修改后的电话\n");scanf("%s",&a[i].phone);printf("修改后的地址\n");scanf("%s",&a[i].address);break;}}if(f == 0){printf("未找到该联系人");}printf("如果你想继续修改联系人请按y\n");printf("或者按任意键退出\n");getchar();scanf("%c",&cn);}while(cn == 'y');
}
void file (){FILE *f;if( ( f = fopen("list.txt","w")) == NULL){printf("打开失败\n");exit(-1);}else{int i = 0;while(i<now){fwrite(&a[i],sizeof(List),1,f);i++;}}fclose(f);
}
int main (){copy();menu();file();return 0;
}
- 感想
这是作者第一次写博客,本人是一名在读大学生,希望通过写博客能提高自己,帮助他人,让我们一起成长!!!
C语言之通讯录的制作并用文件存储相关推荐
- 开源一个自己用go语言加mangos-go消息中间件制作的文件同步工具
介绍 mangos-file是一款基于mangos-go消息中间件纯go语言研发的专门用于文件传输同步工具 编译好的版本(包含win64,amd64,arm64): 已编译稳定版本0.0.8,cs ...
- 电影媒体行业内容存储库制作渲染文件存储设备解决方案
概述 NetApp 帮助广播公司.电影公司.有线电视提供商和互联网交付网络解决它们面对的大媒体挑战. 电影 后期制作需要使用更多带宽来提高分辨率,为更大规模的编辑工作组提供支持. 视觉效果和动画制片公 ...
- c语言intrins头文件,结合单片机学习板学习c语言之流水灯制作 intrins.h头文件
原标题:结合单片机学习板学习c语言之流水灯制作 intrins.h头文件 目的:实现流水灯. 本文引用地址:http://www.eepw.com.cn/article/201608/294948.h ...
- C语言实现通讯录【二】(动态内存开辟,文件数据存储)
C语言实现通讯录[二] 在C语言实现通讯录[一]的基础上进行优化,主要实现两大模块: 动态内存开辟 文件数据存储 动态内存开辟: 考虑到通讯录的大小无法固定,在C语言实现通讯录[一]版本上定义一个足够 ...
- C语言基础14——文件操作。文本文件或二进制文件读写。通讯录的改造。文件缓冲区讲解
目录 为什么使用文件? 什么是文件? 文件的打开和关闭 文件指针 文件的打开和关闭 文件的打开方式 流 重定义文件 文件流 文件的顺序读写 以字符形式读写文本文件 fputc()函数 fgetc()函 ...
- 可文件存储的动态通讯录(C语言)
目录 通讯录结构体 第一次启动通讯录 通讯录初始化 通讯录扩容 导出文件中存储的数据 数据导入文件 传送门(全代码) 通讯录是个结构体数组,而数组的特性就是一次给定一个固定的大小之后是不可以增容的,但 ...
- C语言实现通讯录(含文件保存)
目录 1.测试结果 2.整体思路 3.结构体的定义 4.核心函数搭建 5.模块代码解读 (1).显示菜单 (2).初始化通讯录 (3).给通讯录增加容量 (4).增加联系人 (5).查找联系人 (6) ...
- 从0开始学c语言 - 34 - 通讯录 -静态、动态、存到文件(三种版本)
上一篇:从0开始学c语言-33-动态内存管理_阿秋的阿秋不是阿秋的博客-CSDN博客 我发现,理论的学习文章没几个人看,如果是这种实践类型的文章,看的人很多,偏偏我之前都是扔完代码就走了,也没认真写这 ...
- c语言通讯录二分查找,C语言程序设计 通讯录程序.doc
<C语言程序设计 通讯录程序.doc>由会员分享,可在线阅读,更多相关<C语言程序设计 通讯录程序.doc(28页珍藏版)>请在人人文库网上搜索. 1.目录:课 程 设 计 任 ...
最新文章
- GeenMedical让你知道本领域哪家强,该谁才是真同行,统计检索结果一作、通讯、关键字和国人发文
- python 可以 从视频中 直接剪辑音频出来(亲测MP4)
- php json存mysql斜杠_MySQL 存储php中json_encode格式中文问题及解决
- Python四道面试题
- 直播未来属于RTMP还是HTTP?
- LintCode 1210. 升序子序列(DFS)
- try-catch-finally的执行顺序
- oracle 字符格式化,Oracle 字段格式化[日期,金额]
- 历时3个月,我们是如何为一个开源项目集资300万美元的?
- java中$和 的区别详解_MyBatis中#{}和${}的区别详解
- 习题3-6 纵横字谜的答案(Crossword Answers, ACM/ICPC World Finals 1994, UVa232)
- 分布式机器学习联邦学习论文阅读笔记(持续更新)
- WindowsMac本地搭建Code-Push-Server热更新服务器
- 谷歌邮箱SMTP小白教程
- mongoDB 4.0 开启远程访问
- python中turtle画树
- RTT Nano学习笔记 8 - 信号量
- 人工智能数学基础10:域、函数及相关概念
- svn发布网站(转载于badb0y)
- 表格的常用属性介绍:
热门文章
- 2020高级操作系统 复习考点(五)
- 如何抓取淘宝天猫上多个宝贝商品图片视频素材
- 华为手机永久关闭/开启系统更新(通过ADB模式)
- 保姆级Git入门教程,万字详解
- 51单片机应用篇-- --智能门锁
- STM32用IIC实现EEPROM的读写
- PaddleOCR百度开源—文字识别OCR windows端口本地部署使用
- 高校供需撮合交易平台规范管理及创新发展
- 实现计算体积关键算法。根据输入的半径值,计算球的体积。输入数据有多组,每组占一行,每行包括一个实数,表示球的半径。输出对应球的体积,对于每组输入数据,输出一行,计算结果保留三位小数。
- java 扰码工具_【Developer Log】ProGuard扰码可执行JAR包