C语言实现简单的电子通讯录2

这两天学完系统调用和标准IO,之前的通讯录可以进行一些改进,将数据保存到文件中(图我这里就不发了)。

原理:每次启动程序时先从预设文件中以只读的形式读取保存的通讯录信息,然后将读取到的信息导入到结构体中;每次执行退出时,先将预设文件以更新方式打开,并将文件中之前保存的信息清空,然后将结构体的数据保存到文件中去,再退出程序。
还有在文件写入时和读取时,先写入(读取)保存数据的总个数,让程序知道有多少数据要写入(读取),然后保存每个数据的字节数(程序会根据每个数据的字节数来进行保存),最后再保存数据。

与之前版本相比,改动的只有主函数中加入了读取文件和写入数据这两个步骤,还有的变动就是结构体从一个变成了两个,将指针从原来一个结构体中分离出来,方便数据从文件中的导入导出。下面是代码(免得你们往前翻,我把之前的代码都修改了考过来):

头文件 head.h 唯一修改的就是结构体

#ifndef HEAD_H_
#define HEAD_H_#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>             // sleep函数头文件
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>#define uint unsigned int
#define OK            0
#define ERROR         -1
#define MALLOC_ERROR  -2
#define N             20 typedef int ElementType;
typedef struct data
{ElementType ID;             // ID号char Name [N];              // 姓名char Mobile_Phone [N];      // 手机号码char Home_Address [N];      // 家庭住址char Company_Tell [N];      // 公司电话}Data;
typedef struct _Node
{Data data;struct _Node* next;         // 节点指针
}Node;typedef Node* PNode;            // 重命名节点指针类型//显示操作界面
int Interface_Display ();//添加好友信息 (尾插法)
int Add_Friend (PNode head, ElementType num);//显示所有好友信息
int Friend_Information (PNode head);//查找好友
int Search_Friend (PNode head, char* Name);//删除好友
void Delete_Friend (PNode head, char* Name);#endif

源文件 head.c 关于结构体的部分要进行修改

#include "head.h"//显示操作界面
int Interface_Display ()
{system ("clear");printf ("\t*****************************************\n");printf ("\t~          欢迎使用通讯录               ~\n");printf ("\t~                                       ~\n");printf ("\t~      1 >>>>>>>> 添加好友信息          ~\n");printf ("\t~      2 >>>>>>>> 列表好友信息          ~\n");printf ("\t~      3 >>>>>>>> 搜索好友              ~\n");printf ("\t~      4 >>>>>>>> 删除好友              ~\n");printf ("\t~      5 >>>>>>>> 退出                  ~\n");printf ("\t~                                       ~\n");printf ("\t~                                       ~\n");printf ("\t~                        作者:believe  ~\n");printf ("\t*****************************************\n");printf ("                                           \n");printf ("                                           \n");printf ("\t请输入对应数字选择相应功能:");
}//添加好友信息 (尾插法)
int Add_Friend (PNode head, ElementType num)
{if (NULL == head){return ERROR;}//创建一个新的结点PNode p = (PNode) malloc(sizeof(Node)/sizeof(char));if (NULL == p){return MALLOC_ERROR;}//将新数据赋给新结点system("clear");    printf ("\t*************添加好友***************\n");p->data.ID = num;printf ("\t好友的ID为:%d\n", p->data.ID);printf ("\n");printf ("\t请输入好友的名字:");scanf  ("%s", p->data.Name);printf ("\n");printf ("\t请输入好友的手机号:");scanf  ("%s", p->data.Mobile_Phone);printf ("\n");printf ("\t请输入好友的家庭住址:");scanf  ("%s", p->data.Home_Address);printf ("\n");printf ("\t请输入好友的公司电话:");scanf  ("%s", p->data.Company_Tell);printf ("\n");p->next = NULL;//找到最后一个结点PNode Ptmp;                 //将头结点地址给临时指针PtmpPtmp = head;while (Ptmp->next){Ptmp = Ptmp->next;}Ptmp->next = p;return OK;}//显示所有好友信息
int Friend_Information (PNode head)
{if (NULL == head){return ERROR;}PNode p = head->next;printf ("\tID\t姓名\t\t手机号\t\t住址\t\t\t公司电话\n");while (p){printf ("\t%d\t%s\t\t%s\t\t%s\t\t\t%s\n", p->data.ID, p->data.Name,p->data.Mobile_Phone, p->data.Home_Address, p->data.Company_Tell);p = p->next;}putchar('\n');return OK;
}//通过名字查找好友
int Search_Friend (PNode head, char* Name)          
{PNode p = head;PNode q = NULL;if ((NULL != p) && NULL != (p->next)){while (p->next) {q = p->next;if ((NULL != q) && 0 == (strcmp(q->data.Name, Name))){printf ("\t好友信息: \n\tID:%d\n\t姓名: %s\n\t手机号码: %s\n\t家庭地址:%s\n\t公司电话: %s\n", q->data.ID, q->data.Name, q->data.Mobile_Phone, q->data.Home_Address, q->data.Company_Tell);}else{printf ("\t对不起,您的通讯录没有该好友!\n");}p = p->next;}}/*  另一种做法if (NULL == head){return ERROR;}PNode p;int flag = 1;for (p = head->next; p != NULL; p = p->next){if (0 == strcmp(p->data.Name, Name)){flag = 0;printf ("\t好友信息:\n\tID: %d\n\t姓名: %s\n\t手机号码: %s\n\t家庭地址: %s\n\t公司电话: %s\n", p->data.ID, p->data.Name, p->data.Mobile_Phone, p->data.Home_Address, p->data.Company_Tell);}}fi (flag){printf ("\t对不起,您的通讯录没有该好友!\n");}putchar('\n');*/return OK;
}//删除好友
void Delete_Friend (PNode head, char* Name)
{PNode p = head;PNode q = NULL;while (NULL != p && NULL != (p->next)){q = p->next;if (NULL != q && 0 == strcmp(q->data.Name, Name)){p->next = q->next;free(q);int j;printf ("\t正在删除\n");printf ("\t请稍候");fflush (stdout);            //强制刷新缓存,输出显示for (j = 0; j < 2; j++){sleep (1);              //linux使用sleep,参数为秒printf (".");fflush(stdout);         //强制刷新缓存,输出显示}printf ("\n");printf ("\t该好友已成功删除!\n");}else if (NULL == q->next && 0 != strcmp(q->data.Name, Name)){printf ("\t您的通讯录没有该好友!\n");}p = p->next;}
}

主函数 main.c 加入了数据的读取和写入,已标明

/*******************************************************************
需求:制作一个电子通讯录,通过该通讯录能录入好友ID号、姓名(英文)、手
机号码,家庭住址,公司电话。
模块:主界面:主要显示软件功能,A)添加好友信息 B)列表好友信息。(包含排序功能) C)搜索好友 D)删除好友A)用户输入INSERT命令后,让用户输入好友信息。添加成功或失败都需提示B)用户输入DISPLAY命令后,好友信息升序排列C)用户输入SEARCH命令后,让用户输入将要搜索好友姓名查询。如果未搜索到请友好提示。如果搜索到,显示处该好友信息D)用户输入DELETE命令后,让用户输入将要删除好友姓名删除,如果存在同名的多个好友,则列表出,所有同名的好友信息,让用户通过输入ID号删除提示用户删除成功。
**********************************************************************/
#include "head.h"int main ()
{int Function;int i = 0;char Name[N];int cho;// 创建头结点并为其分配空间PNode head_node = (PNode) malloc(sizeof(Node)/sizeof(char));if (NULL == head_node){return MALLOC_ERROR;}head_node->next = NULL;/****************************************************************打开存放信息的文件并将里面的数据导入到链表中区
****************************************************************/// 以只读方式打开存放信息的文件,FILE *fp1 = fopen ("student.txt", "r+");  if (NULL == fp1)  {  printf ("fopen");  return -1;  }  PNode tmp = head_node; int count;  int ret;  // 保存读记录的个数并判断是否读到文件结尾,如果读到文件结尾,// 它返回一个非0 的值ret = fread (&count, sizeof(int), 1, fp1);  if(ret != 0)  {  for (i = 0; i < count; i++)  {// 创建新结点用来保存读取的数据Node *node = (Node*)malloc(sizeof(Node)/sizeof(char));      int len;                    fread (&len, sizeof(int), 1, fp1);      // 读取数据长度fread (&(node->data), len, 1, fp1);     // 读取数据  node->next = NULL;      while (tmp->next)                       // 向后遍历{  tmp = tmp->next;  }  tmp->next = node;                       // 将结点导入链表中 }  } if (ret == 0 && !feof(fp1))                     // 读取失败{  perror ("fread");  return -1;  }  fclose (fp1);                                   // 关闭刚刚打开的文件
/****************************************************************文件导入链表结束,关闭文件
****************************************************************/   i = 1;                              // i初始化(i既是ID编号)while (1){Interface_Display ();           // 主界面scanf ("%d", &Function);switch (Function)               // 功能选择{case 1:                     // 添加好友{Function = 0;Add_Friend (head_node, i++);int j;printf ("\t正在添加\n");printf ("\t请稍候");fflush (stdout);        // 强制刷新缓存,输出显示for (j = 0; j < 2; j++){sleep (1);          // Linux 使用sleep,参数为秒printf (".");fflush (stdout);    // 强制刷新缓存,输出显示}printf ("\n");printf ("\t添加成功!\n");printf ("\t返回主菜单请输入1:");scanf ("%d", &cho);if (1 == cho){break;}else{printf ("\t对不起!您的输入有误!请重新输入:");scanf ("%d", &cho);break;}break;}           case 2:                 // 显示好友信息{system ("clear");printf ("\t***********好友信息******************\n");printf ("\n");Friend_Information (head_node);Function = 0;printf ("\t返回主菜单请输入1:");scanf ("%d", &cho);if (1 == cho){break;}else{printf ("\t对不起!您的输入有误!请重新输入:");scanf ("%d", &cho);break;}break;}case 3:                 // 查找好友{system ("clear");printf ("\t*************查找好友*************\n");printf ("\t请输入您要查找的好友姓名:");scanf  ("%s", Name);printf ("\n");int j;          printf ("\t正在查找\n");printf ("\t请稍候");fflush (stdout);        // 强制刷新缓存,输出显示for (j = 0; j < 2; j++){sleep (1);          // Linux 使用sleep,参数为秒printf (".");fflush (stdout);    // 强制刷新缓存,输出显示}printf ("\n");Search_Friend (head_node, Name);printf ("\t返回主菜单请输入1:");scanf ("%d", &cho);if (1 == cho){break;}else{printf ("\t对不起!您的输入有误!请重新输入:");scanf ("%d", &cho);break;}break;}case 4:                     //删除好友{system ("clear");printf ("\t*************删除好友*************\n");printf ("\t请输入要删除好友的姓名:");scanf  ("%s", Name);printf ("\n");Delete_Friend (head_node, Name);printf ("\t返回主菜单请输入1:");scanf ("%d", &cho);if (1 == cho){break;}else{printf ("\t对不起!您的输入有误!请重新输入:");scanf ("%d", &cho);break;}break;}   case 5:                     //退出通讯录{/****************************************************************退出程序前,将链表中的数据导入到文件中去
****************************************************************/// 以更新方式打开存放信息的文件(打开时会清空文件)FILE *fp2 = fopen ("student.txt", "wb+");  if(NULL == fp2)  {  printf ("fopen");  return -1;  }  tmp = head_node->next;          // tmp为第一个结点count = 0;                      // 用来存放链表长度while(tmp)                      // 求链表长度{  count++;  tmp = tmp->next;  }// 要写入数据的个数fwrite(&count, sizeof(int), 1, fp2);  tmp = head_node;                // tmp初始化while (tmp->next)  {  Node* p = tmp->next;  tmp->next = p->next;  // 写入数据的长度                  int len = sizeof(p->data);  fwrite (&len, sizeof(int), 1, fp2);  //写入数据  fwrite (&(p->data), sizeof(Data), 1, fp2);  free (p);                    }  fclose (fp2);  
/****************************************************************数据保存结束,即将退出程序
****************************************************************/Function = 0;system ("clear");exit (0);}default:                    //输入有误{Function = 0;printf ("\t对不起!您的输入有误!请重新输入:");scanf ("%d", &Function);break;}           }       }   return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/448463.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解决 VS Code 保存时候自动格式化

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 不知道从哪个版本起&#xff0c;VS code 保存会自动格式化。 以前都是altshiftF格式化的&#xff0c;现在一保存就格式化&#xff0c;而…

发布在线文档【软件=业务+架构+流程+组织.pptx】

10年的技术工作&#xff0c;软件这个词对我来说一点都不陌生&#xff0c;但是当我问自己如何理解软件的&#xff1f;我却不知道如何回答。软件&#xff1d;业务&#xff0b;架构&#xff0b;流程&#xff0b;组织&#xff0c;其中公式是借用软件产品线工程BAPO的概念&#xff0…

12种食物最养男人 10种食物最养女人 太值得收藏了

据统计&#xff0c;男性10大死因中有4项与饮食有关&#xff0c;包括癌症、脑血管疾病、心脏病和糖尿病。以下12种食品对男性健康有益&#xff0c;建议男性多多摄取。 男人需要的十种养生食物 No.1西红柿 西红柿的酸味能促进胃液分泌&#xff0c;帮助消化蛋白质等&#xff…

ES 基础

1. ES 基础一网打尽 1.1 ES定义 ESelaticsearch简写&#xff0c; Elasticsearch是一个开源的高扩展的分布式全文检索引擎&#xff0c;它可以近乎实时的存储、检索数据&#xff1b;本身扩展性很好&#xff0c;可以扩展到上百台服务器&#xff0c;处理PB级别的数据。 Elasticsear…

为什么 那么多 前端开发者都想学 Vue.js

根据JavaScript 2017 前端库状况调查 Vue.js是开发者最想学的前端库。我在这里说明一下我为什么认为这也是和你一起通过使用 Vue 构建一个简单的 App 应用程序的原因。 我最近曾与 Evan You&#xff0c;Chris Fritz&#xff0c;Sarah Drasner&#xff0c;和 Adam Jahr 做了一个…

进程间通信之管道通信

两个程序之间传递数据的一种简单方法是使用popen和pclose。 #include <stdio.h> FILE *popen(const char *command, const char *type); int pclose(FILE *stream); popen函数允许一个程序将另一个程序作为新进程来启动&#xff0c;并可以传递数据给它或者通过它接收数据…

vue 各组件 使用 Demo

环境搭建 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 假设你已经通读vue官方文档&#xff08;文档都没读一遍&#xff08;至少&#xff09;&#xff0c;那不建议动手撸码&#xff…

Dropbox推独立应用,公司估值已达100亿美元

摘要&#xff1a;Dropbox刚获得5亿美元的新一轮融资&#xff0c;其估值已高达100亿美元&#xff0c;现在又推出针对云服务的独立应用Carousel&#xff0c;不久之后&#xff0c;还会有应用陆续推出&#xff0c;随着美国前国务卿赖斯的加盟&#xff0c;Dropbox在云市场的表现异常…

SQL经典面试题(二)

有3个表S&#xff0c;C&#xff0c;SCS&#xff08;SNO&#xff0c;SNAME&#xff09;代表&#xff08;学号&#xff0c;姓名&#xff09; //主键&#xff1a;SNO //多个人&#xff0c;多门课 3张表 &#xff0c;SC 关系表C&#xff08;CNO&#xff0c;CNAME&#xff0c;…

进程间通信之信号he信号量

信号的篇幅较少&#xff0c;就把他和信号量放在一起了。先讲讲他们之间的区别&#xff1a; 1.信号&#xff1a;&#xff08;signal&#xff09;是一种处理异步事件的方式。信号时比较复杂的通信方式&#xff0c;用于通知接受进程有某种事件发生&#xff0c;除了用于进程外&…

开源当自强:我们不是“便宜货”

之前人们争相使用开源软件&#xff0c;无非是因为它便宜、好用、易得&#xff0c;不过根据最新的开源软件调查显示&#xff0c;人们使用开源软件最主要的原因还是看重它的高质量。 成本低是很过公司参与开源项目的最主要原因之一&#xff0c;而现在他们视开源是一条通往创新、省…

前端学习:Vue.js基本使用

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 Vue教程文档&#xff1a; https://cn.vuejs.org/v2/guide/ 定义 实例&#xff1a; new Vue() 挂载点: el 数据&#xff1a;data 模…

PWE

Obstacle Override Logic The obstacle override logic provides the possibility to override obstacle within a window movement by selective switching off the anti-trap functionality.转载于:https://www.cnblogs.com/dannykong/p/11151813.html

进程间通信之消息队列

一、什么是消息队列 unix早期通信机制之一的信号能够传送的信息量有限&#xff0c;管道则只能传送无格式的字节流&#xff0c;这无疑会给应用程序开发带来不便。消息队列&#xff08;也叫做报文队列&#xff09;则克服了这些缺点。 消息队列就是一个消息的链表。可以把消息看…

“ 愿我如星君如月,夜夜流光相皎洁 ...”

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 永远相信爱情 ... 从一而终 ... --------------------------------------------------------------------------- 后记&#xff1a;2…

python内建函数和工厂函数的整理

内建函数参阅&#xff1a; https://www.cnblogs.com/pyyu/p/6702896.html 工厂函数&#xff1a; 本篇博文比较粗糙&#xff0c;后续会深入整理转载于:https://www.cnblogs.com/qiang-upc/p/11155786.html

显卡天梯图:2014最新显卡性能天梯图

随着电脑游戏的推广&#xff0c;很多用户都喜欢上了电脑网络游戏&#xff0c;所以组装电脑用户在装机的时候&#xff0c;会考虑电脑配置的游戏性能&#xff0c;要提高电脑配置游戏性能首要条件就是显卡性能要强&#xff0c;如果显卡性能不佳&#xff0c;那么其它方面性能再强&a…

进程间通信之分别用共享内存和信号量实现卖票

利用共享内存实现的卖票系统&#xff1a; 利用flag来保证同一时间只有一个程序使用内存&#xff0c;使用结束还原。 #include <stdio.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/types.h> #include <string.h> #include <…

shiro 的 @RequiresPermissions 注解使用

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 权限控制是shiro最核心的东西 Shiro权限声明通常是使用以冒号分隔的表达式。一个权限表达式可以清晰的指定资源类型&#xff0c;允许的…

【显卡天梯图】2014年最新显卡天梯图 – 【迄今最全系列显卡】

【显卡天梯图】2014年最新显卡天梯图 – 【迄今最全系列显卡】 随着电脑游戏的推广&#xff0c;很多用户都喜欢上了电脑网络游戏&#xff0c;所以组装电脑用户在装机的时候&#xff0c;会考虑电脑配置的游戏性能&#xff0c;要提高电脑配置游戏性能首要条件就是显卡性能要强&am…