【C语言】通讯录3.0 (文件存储版)

简介: 通讯录是一种记录联系人信息的工具,包括姓名、电话号码、电子邮件地址、住址等。文章的一二三章均于上一篇相同,可以直接看第四章改造内容。此通讯录是基于通讯录2.0(动态增长版)的基础上进行增加文件操作功能,请先看系列文章第二篇,再看本篇博客。

前言

通讯录是一种记录联系人信息的工具,包括姓名、电话号码、电子邮件地址、住址等。

文章的一二三章均于上一篇相同,可以直接看第四章改造内容。

此通讯录是基于通讯录2.0(动态增长版)的基础上进行增加文件操作功能,请先看系列文章第二篇,再看本篇博客。

****** 有需要源代码,见文章末尾 ******


系列文章目录

第一篇:【C语言】通讯录1.0 (静态版)

第二篇:【C语言】通讯录2.0 (动态增长版)

第三篇:【C语言】通讯录3.0 (文件存储版)


文章目录

前言

系列文章目录

一、什么是通讯录

二、静态版、动态增长版和文件存储版的区别

1. 静态版

2. 动态增长版

3. 文件存储版

三、通讯录模块组成(图文)

1. 通讯录文件构成

2. 通讯录个人信息

3. 通讯录功能模块

四、改造通讯录2.0(改造目标)

1. 文件存储通讯录要求

2. 需要添加的功能模块

五、如何改进(代码演示)

1. 建立文件

2. 写入文件

3. 读取文件

六、所有文件代码

1.头文件

2. 函数文件

3. 逻辑测试文件

总结


一、什么是通讯录

通讯录是一种记录联系人信息的工具,包括姓名、电话号码、电子邮件地址、住址等。通讯录可以帮助人们管理自己的联系人,让人们更轻松地与他人保持联系。通讯录可以在手机、电脑、笔记本等设备上保存,也可以在云端储存和同步,方便用户随时查看和更新联系人信息。


二、静态版、动态增长版和文件存储版的区别

C语言静态版、动态增长版和文件存储版的区别如下:


1. 静态版

静态版:在程序编译时就确定了内存大小,程序运行期间内存大小不会发生变化,因此对于需要处理大量数据或者不确定数据大小的情况不适用。


2. 动态增长版

动态增长版:可以在程序运行期间根据需要动态增加内存大小,因此适用于处理不确定数据大小的情况。但是动态增长的内存需要手动释放,否则会导致内存泄漏。


3. 文件存储版

文件存储版:将数据存储在文件中,可以持久保存数据并随时读取。但是存储在文件中的数据需要进行IO操作,因此相比于内存操作来说效率较低。此外,文件存储版不适用于需要频繁修改的数据。


三、通讯录模块组成(图文)


1. 通讯录文件构成

image.png

2. 通讯录个人信息

image.png

3. 通讯录功能模块

image.png


四、改造通讯录2.0(改造目标)


1. 文件存储通讯录要求

  1. 将通讯录的联系人信息可以保存在文件里
  2. 保存到通讯录里的文件以二进制文件保存
  3. 第二次打开时,读取文件里上一次保存的联系人信息


2. 需要添加的功能模块

image.png


五、如何改进(代码演示)


1. 建立文件

  • 使用文件操作 fopen 函数来建立一个文件
FILE*pf=fopen("data.dat","wb");
if (pf==NULL)
    {
perror("SaveContact");
return;
    }


2. 写入文件

  • 使用文件操作 fwrite 函数
  • 使用for循环,依次将通讯录内容写入文件
//写入文件voidSaveContact(Contact*pc)
{
FILE*pf=fopen("data.dat","wb");
if (pf==NULL)
    {
perror("SaveContact");
return;
    }
inti=0;
for (i=0; i<pc->sz; i++)
    {
fwrite(pc->data+i, sizeof(PeoInfo), 1, pf);
    }
fclose(pf);
pf=NULL;
printf("保存成功\n");
}


3. 读取文件

  • 使用文件操作 fread 函数
  • 使用whlie循环,先判断fread的返回值,为真进入循环
  • 使用扩容函数 determine( ) 来判断内存是否充足,进行增容
//读取文件voidReadContact(Contact*pc)
{
FILE*pf=fopen("data.dat", "rb");
if (pf==NULL)
    {
perror("ReadContact");
return;
    }
PeoInfotem= { 0 };
while (fread (&tem, sizeof(PeoInfo), 1, pf))
    {
if (determine(pc) ==0)
        {
return;
        }
pc->data[pc->sz] =tem;
pc->sz++;
    }
fclose(pf);
pf=NULL;
}


六、所有文件代码


1.头文件

#pragma once#include<stdio.h>#include<assert.h>#include<string.h>#include<stdlib.h>#define MAX 100#define NAME 10#define SEX  5#define TELE 12#define ADDR 30//使用枚举  定义选择   enumOPTION{
EXIT,//0ADD,
DEL,
SEARCH,
MODIFY,
SHOW,
SORT};
//个人信息类型声明typedefstructPeoInfo{
charname[NAME];
intage;
charsex[SEX];
chartele[TELE];
charaddr[ADDR];
}PeoInfo;
//建立通讯录//静态版//typedef struct Contact//{//  PeoInfo data[MAX]; //通讯录数量//  int sz;             //目前通讯录内的人数 //}Contact;//动态版typedefstructContact{
PeoInfo*data;
intsz;
intcapacity;
}Contact;
//函数声明//初始化通讯录voidInitContact(Contact*pc);
//增加联系人voidAddContact(Contact*pc);
//显示所有联系人的信息voidShowContact(constContact*pc);
//删除指定联系人voidDelContact(Contact*pc);
//查找指定联系人voidSearchContact(constContact*pc);
//修改指定联系人voidModifyContact(Contact*pc);
//释放内存voidDestroyContact(Contact*pc);
//保存通讯录voidSaveContact(Contact*pc);

2. 函数文件

#define _CRT_SECURE_NO_WARNINGS 1#include "addbook.h"voidReadContact(Contact*pc);
//静态版//void InitContact(Contact* pc)//{//  assert(pc);   //断言//  memset(pc->data, 0, sizeof(pc->data));   //内存函数  data初始化为0  //  pc->sz = 0;//}intdetermine(Contact*pc)
{
assert(pc);
if (pc->capacity==pc->sz)
    {
PeoInfo*ptr= (PeoInfo*)realloc(pc->data, (pc->capacity+2) *sizeof(PeoInfo));
if (ptr==NULL)
        {
perror("determine");
return0;
        }
else        {
pc->capacity+=2;
pc->data=ptr;
printf("增容成功\n");
return1;
        }
    }
return1;
}
//动态版voidInitContact(Contact*pc)
{
assert(pc);
pc->data= (PeoInfo*)malloc(3*sizeof(PeoInfo));
if (pc->data==NULL)
    {
perror("InitContact");
return;
    }
pc->capacity=3;
pc->sz=0;
ReadContact(pc);
}
//动态版voidAddContact(Contact*pc)
{
assert(pc);       //断言if (determine(pc) ==0)
    {
return;
    }
printf("请输入姓名:>");
scanf("%s", pc->data[pc->sz].name);
printf("请输入年龄:>");
scanf("%d", &(pc->data[pc->sz].age));
printf("请输入性别:>");
scanf("%s", pc->data[pc->sz].sex);
printf("请输入电话:>");
scanf("%s", pc->data[pc->sz].tele);
printf("请输入地址:>");
scanf("%s", pc->data[pc->sz].addr);
pc->sz++;    //通讯录加1printf("联系人增加成功\n");
}
//静态版//void AddContact(Contact* pc)//{//  assert(pc);       //断言//  if (pc->sz == MAX)         //如果通讯录已经满了  则返回//  {//      printf("通讯录已满,无法添加\n");//      return;//  }//  printf("请输入姓名:>");//  scanf("%s", pc->data[pc->sz].name);//  printf("请输入年龄:>");//  scanf("%d", &(pc->data[pc->sz].age));//  printf("请输入性别:>");//  scanf("%s", pc->data[pc->sz].sex);//  printf("请输入电话:>");//  scanf("%s", pc->data[pc->sz].tele);//  printf("请输入地址:>");//  scanf("%s", pc->data[pc->sz].addr);//  pc->sz++;    //通讯录加1//  printf("联系人增加成功\n");//}//搜索名字找通讯录函数staticintFindname(constContact*pc, charna[])
{
inti=0;
assert(pc&&na);
for (i=0; i<pc->sz; i++)
    {
if (strcmp(pc->data[i].name, na) ==0)
        {
returni;
        }
    }
return-1;
}
voidDelContact(Contact*pc)
{
if (pc->sz==0)
    {
printf("通讯录为空\n");
return;
    }
charname[NAME] = { 0 };
assert(pc);
//输入要查找的联系人名字printf("请输入要查找的名字:>");
scanf("%s", &name);
//找到要查找的联系人intdel=Findname(pc, name);
//删除坐标位子的联系人 ,将后面的联系人进行代替其位置if (del==-1)
    {
printf("找不到,此人不存在\n");
return;
    }
else    {
inti=0;
for (i=del; i<pc->sz; i++)
        {
pc->data[i] =pc->data[i+1];
        }
pc->sz--;
    }
printf("成功删除联系人\n");
}
voidShowContact(constContact*pc)
{
assert(pc);
printf("%-10s\t%-4s\t%-5s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址");
inti=0;
for (i=0; i<pc->sz; i++)
    {
printf("%-10s\t%-4d\t%-5s\t%-12s\t%-30s\n",
pc->data[i].name,
pc->data[i].age,
pc->data[i].sex,
pc->data[i].tele,
pc->data[i].addr);
    }
printf("通讯录展示完毕\n");
}
voidSearchContact(constContact*pc)
{
if (pc->sz==0)
    {
printf("通讯录为空\n");
return;
    }
charname[NAME] = { 0 };
assert(pc);
//输入要查找的联系人名字printf("请输入要查找的名字:>");
scanf("%s", &name);
//找到要查找的联系人inti=Findname(pc, name);
if (i==-1)
    {
printf("找不到,此人不存在\n");
return;
    }
else    {
printf("%-10s\t%-4s\t%-5s\t%-12s\t%-30s\n", "名字", "年龄", "性别", "电话", "地址");
printf("%-10s\t%-4d\t%-5s\t%-12s\t%-30s\n",
pc->data[i].name,
pc->data[i].age,
pc->data[i].sex,
pc->data[i].tele,
pc->data[i].addr);
    }
printf("成功找到联系人\n");
}
voidModifyContact(Contact*pc)
{
assert(pc);
charname[NAME] = { 0 };
printf("请输入要修改人的名字:>");
scanf("%s", &name);
intmod=Findname(pc, name);
if (mod==-1)
    {
printf("找不到,不存在\n");
return;
    }
else    {
printf("请输入姓名:>");
scanf("%s", pc->data[mod].name);
printf("请输入年龄:>");
scanf("%d", &(pc->data[mod].age));
printf("请输入性别:>");
scanf("%s", pc->data[mod].sex);
printf("请输入电话:>");
scanf("%s", pc->data[mod].tele);
printf("请输入地址:>");
scanf("%s", pc->data[mod].addr);
printf("联系人修改成功\n");
    }
}
voidDestroyContact(Contact*pc)
{
free(pc->data);
pc->data=NULL;
pc->capacity=0;
pc->sz;
}
//写入文件voidSaveContact(Contact*pc)
{
FILE*pf=fopen("data.dat","wb");
if (pf==NULL)
    {
perror("SaveContact");
return;
    }
inti=0;
for (i=0; i<pc->sz; i++)
    {
fwrite(pc->data+i, sizeof(PeoInfo), 1, pf);
    }
fclose(pf);
pf=NULL;
printf("保存成功\n");
}
//读取文件voidReadContact(Contact*pc)
{
FILE*pf=fopen("data.dat", "rb");
if (pf==NULL)
    {
perror("ReadContact");
return;
    }
PeoInfotem= { 0 };
while (fread (&tem, sizeof(PeoInfo), 1, pf))
    {
if (determine(pc) ==0)
        {
return;
        }
pc->data[pc->sz] =tem;
pc->sz++;
    }
fclose(pf);
pf=NULL;
}

3. 逻辑测试文件

#define _CRT_SECURE_NO_WARNINGS 1#include"addbook.h"voidmenu()
{
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");
}
voidtest()
{
intinput=0;
Contactcon;
InitContact(&con);
do    {
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
        {
caseADD:
AddContact(&con);
break;
caseDEL:
DelContact(&con);
break;
caseSEARCH:
SearchContact(&con);
break;
caseMODIFY:
ModifyContact(&con);
break;
caseSHOW:
ShowContact(&con);
break;
caseSORT:
printf("功能待开发\n");
break;
caseEXIT:
SaveContact(&con);
DestroyContact(&con);
printf("成功退出通讯录\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
        }
    } while (input);
}
intmain()
{
test();
return0;
}

总结

本期博客,是通讯录3.0(文件存储版),是对前面所学知识进行复习,编写通讯录时有助于理解自定义类型、动态内存管理及文件操作的学习和了解,通讯录的文章到这里就结束了,谢谢支持!!!


如这篇博客对大家有帮助的话,希望 三连 支持一下 !!! 如果有错误感谢大佬的斧正 如有 其他见解发到评论区,一起学习 一起进步。

目录
相关文章
|
1天前
|
存储 C语言
手把手教你用C语言实现通讯录管理系统
手把手教你用C语言实现通讯录管理系统
|
5月前
|
C语言
C语言——通讯录系统—基于 VS2022
C语言——通讯录系统—基于 VS2022
|
2月前
|
存储 数据可视化 Serverless
【C语言】C语言-学籍管理系统(源码+文件存储)【独一无二】
【C语言】C语言-学籍管理系统(源码+文件存储)【独一无二】
|
2月前
|
存储 搜索推荐 算法
【C语言】C语言—通讯录管理系统(源码)【独一无二】
【C语言】C语言—通讯录管理系统(源码)【独一无二】
|
2月前
|
存储 数据可视化 C语言
【C语言】C语言 手机通讯录系统的设计 (源码+数据+论文)【独一无二】
【C语言】C语言 手机通讯录系统的设计 (源码+数据+论文)【独一无二】
|
4月前
|
机器学习/深度学习 搜索推荐 程序员
C语言实现个人通讯录(功能优化)-2
C语言实现个人通讯录(功能优化)
C语言实现个人通讯录(功能优化)-2
|
4月前
|
存储 C语言 索引
C语言实现个人通讯录(功能优化)-1
C语言实现个人通讯录(功能优化)
C语言实现个人通讯录(功能优化)-1
|
4月前
|
C语言
C语言学习记录——通讯录(静态内存)
C语言学习记录——通讯录(静态内存)
29 2
|
4月前
|
存储 人机交互 C语言
【C语言项目实战】使用单链表实现通讯录
【C语言项目实战】使用单链表实现通讯录
|
5月前
|
存储 C语言
C语言实现通讯录
C语言实现通讯录
38 2