通讯录文件版本

简介: 文件版本的通讯录,可以保存

1.contact.c

include"contact.h"

void checkcapity(contact* p);

void loadcontact(contact* p)//将文件中的内容加载进入

{

   person tmp = { 0 };

   FILE* pfread = fopen("data.txt", "rb");

   if (pfread == NULL)

   {

       perror("loadcontact::fopen");

       return;

   }

   while (fread(&tmp, sizeof(person), 1, pfread))

   {

       checkcapity(p);

       p->data[p->sz] = tmp;

       p->sz++;

   }

   fclose(pfread);

   pfread = NULL;

}

void init(contact* p)

{

   p->data = (person)malloc(3sizeof(person));

   if (p->data == NULL)

   {

       return;

   }

   p->sz = 0;

   p->capity = 3;

   loadcontact(p);

}

void checkcapity(contact* p)

{

   if (p->sz == p->capity)//空间已满 要扩容

   {

       struct person* ptr = (struct person*)realloc(p->data, (p->capity + 2) * sizeof(struct person));//addcap代表增大2个容量

       if (ptr != NULL)

       {

           p->data = ptr;

           p->capity = p->capity + 2;//将容量扩大到5 str不需要销毁 它并没有开辟动态空间

           printf("扩容成功\n");

       }

   }

}

void addcontact(contact* p)//增加通讯录成员

{

   checkcapity(p);

   printf("请输入名字:>");

   scanf("%s", p->data[p->sz].name);

   printf("请输入年龄:>");

   scanf("%d", &p->data[p->sz].age);

   printf("请输入性别:>");

   scanf("%s", p->data[p->sz].sex);

   printf("请输入电话:>");

   scanf("%s", p->data[p->sz].tele);

   printf("请输入地址:>");

   scanf("%s", p->data[p->sz].addr);

   p->sz++;

   printf("增加成功\n");

}

int find(contact* p, char name[])

{

   int i = 0;

   for (i = 0; i < p->sz; i++)

   {

       if (strcmp(name, p->data[i].name) == 0)

       {

           return i;

       }

   }

   return -1;

}

void delcontact(contact* p)//删除通讯录成员

{

   if (p->sz == 0)

   {

       printf("没有数据可以删除\n");

       return;

   }

   char name[20];

   printf("请删除输入名字:>");

   scanf("%s", name);

   int ret = find(p, name);

   if (ret == -1)

   {

       printf("没找到\n");

       return;

   }

   else

   {

       int i = 0;

       for (i = 0; i < p->sz - 1; i++)//数据到达倒数第二个就会把倒数第一个数传过来

       {

           p->data[i] = p->data[i + 1];

       }

       p->sz--;//一共有两个倒数第一个的数的值 故删去最后一个数

   }

}

void searchcontact(const contact* p)//查找通讯录成员

{

   char name[20];

   printf("输入要查找的名字:>");

   scanf("%s", name);

   int ret = find(p, name);

   if (ret == -1)

   {

       printf("没找到\n");

       return;

   }

   else

   {

       printf("%20s\t %5s\t %5s\t %20s\t %20s\n", "名字", "年龄", "性别", "电话", "地址");

       printf("%20s\t", p->data[ret].name);

       printf("%5d\t", p->data[ret].age);

       printf("%5s\t", p->data[ret].sex);

       printf("%20s\t", p->data[ret].tele);

       printf("%20s\n", p->data[ret].addr);

   }

}

void modifycontact(contact* p)//修改通讯录成员

{

   char name[20];

   printf("输入名字:>");

   scanf("%s", name);

   int ret = find(p, name);

   if (ret == -1)

   {

       printf("没找到该成员\n");

   }

   else

   {

       printf("请输修改入名字:>");

       scanf("%s", p->data[ret].name);

       printf("请输入修改年龄:>");

       scanf("%d", &p->data[ret].age);

       printf("请输入修改性别:>");

       scanf("%s", p->data[ret].sex);

       printf("请输入修改电话:>");

       scanf("%s", p->data[ret].tele);

       printf("请输入修改地址:>");

       scanf("%s", p->data[ret].addr);

   }

}

void printcontact(contact* p)//输出所有成员

{

   int i = 0;

   printf("%20s\t %5s\t %5s\t %20s\t %20s\n", "名字", "年龄", "性别", "电话", "地址");

   for (i = 0; i < p->sz; i++)

   {

       printf("%20s\t", p->data[i].name);

       printf("%5d\t", p->data[i].age);

       printf("%5s\t", p->data[i].sex);

       printf("%20s\t", p->data[i].tele);

       printf("%20s\n", p->data[i].addr);

   }

}

int cmp(const void* e1, const void* e2)

{

   return ((struct person)e1)->age - ((struct person)e2)->age;

}

void sortcontact(contact* p)//将结构体成员排序

{

   qsort(p->data, p->sz, sizeof(struct person), cmp);

}

void savecontact(contact* p)

{

   FILE* pf = fopen("data.txt", "wb");//创建文件

   if (pf == NULL)

   {

       perror("savecontact::fopen");

       return;

   }

   int i = 0;

   for (i = 0; i < p->sz; i++)//将内容写入文件

   {

       fwrite(p->data + i, sizeof(person), 1, pf);

   }

fclose(pf);//关闭文件
pf = NULL;

}

void destory(contact* p)

{

   free(p->data);

   p->data = NULL;

   p->capity = 0;

   p->sz = 0;

}

2.contact.h

define _CRT_SECURE_NO_WARNINGS

define      cap 3//动态内存空间的初始容量

define   addcap 2//增大的容量

include

include

include

typedef struct person

{

   char name[20];

   int age;

   char sex[20];

   char tele[20];

   char addr[20];

}person;

typedef struct contact

{

   person* data;//指向动态内存空间 用来存放联系人信息

   int sz;//当前记录的个数

   int capity;//动态内存的容量

}contact;

void init(contact* p);

void addcontact(contact* p);

void delcontact(contact* p);

void searchcontact(const contact* p);//这里我们只是寻找数据 不修改 用const修饰结构体本身内容不能被修改 起到保护数据的作用

void modifycontact(contact* p);

void printcontact(contact* p);

void sortcontact(contact* p);

void destory(contact* p);

void loadcontact(contact* p);

void savecontact(contact* p);

3.test.c

include"contact.h"

void menu()

{

   printf("1.add       2.del\n");

   printf("3.search    4.modify\n");     printf("5.sort      6.print\n");     printf("0.ex\n");

}

enum day

{

   ex,

   add,

   del,

   search,

   modify,

   sort,

   print

};

int main()

{

   contact  con;

   init(&con);

   int input = 0;

   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 sort:

           sortcontact(&con);

           break;

       case print:

           printcontact(&con);

           break;

       case ex:

           savecontact(&con);

           printf("结束");

           destory(&con);//销毁内存

           break;

default:
        printf("输入错误 重新输入");
        break;
    }
} while (input);
return 0;

}

相关文章
kde
|
3天前
|
Docker镜像加速指南:手把手教你配置国内镜像源
配置国内镜像源可大幅提升 Docker 拉取速度,解决访问 Docker Hub 缓慢问题。本文详解 Linux、Docker Desktop 配置方法,并提供测速对比与常见问题解答,附最新可用镜像源列表,助力高效开发部署。
kde
1900 6
2025年最新版最细致Maven安装与配置指南(任何版本都可以依据本文章配置)
本文详细介绍了Maven的项目管理工具特性、安装步骤和配置方法。主要内容包括: Maven概述:解释Maven作为基于POM的构建工具,具备依赖管理、构建生命周期和仓库管理等功能。 安装步骤: 从官网下载最新版本 解压到指定目录 创建本地仓库文件夹 关键配置: 修改settings.xml文件 配置阿里云和清华大学镜像仓库以加速依赖下载 设置本地仓库路径 附加说明:包含详细的配置示例和截图指导,适用于各种操作系统环境。 本文提供了完整的Maven安装和配置
2025年最新版最细致Maven安装与配置指南(任何版本都可以依据本文章配置)
Dify MCP 保姆级教程来了!
大语言模型,例如 DeepSeek,如果不能联网、不能操作外部工具,只能是聊天机器人。除了聊天没什么可做的。
529 4
国内如何安装和使用 Claude Code镜像教程 - Windows 用户篇
国内如何安装和使用 Claude Code镜像教程 - Windows 用户篇
338 0
Excel数据治理新思路:引入智能体实现自动纠错【Python+Agent】
本文介绍如何利用智能体与Python代码批量处理Excel中的脏数据,解决人工录入导致的格式混乱、逻辑错误等问题。通过构建具备数据校验、异常标记及自动修正功能的系统,将数小时的人工核查任务缩短至分钟级,大幅提升数据一致性和办公效率。
【保姆级图文详解】大模型、Spring AI编程调用大模型
【保姆级图文详解】大模型、Spring AI编程调用大模型
188 4
【保姆级图文详解】大模型、Spring AI编程调用大模型
让AI时代的卓越架构触手可及,阿里云技术解决方案开放免费试用
阿里云推出基于场景的解决方案免费试用活动,新老用户均可领取100点试用点,完成部署还可再领最高100点,相当于一年可获得最高200元云资源。覆盖AI、大数据、互联网应用开发等多个领域,支持热门场景如DeepSeek部署、模型微调等,助力企业和开发者快速验证方案并上云。
235 17
让AI时代的卓越架构触手可及,阿里云技术解决方案开放免费试用
DeepSeek R1+Open WebUI实现本地知识库的搭建和局域网访问
本文介绍了使用 DeepSeek R1 和 Open WebUI 搭建本地知识库的详细步骤与注意事项,涵盖核心组件介绍、硬件与软件准备、模型部署、知识库构建及问答功能实现等内容,适用于本地文档存储、向量化与检索增强生成(RAG)场景的应用开发。
291 0
数据分析都要会BI?No!不是所有企业都应该上BI
BI工具已成为数据分析行业的标配,广泛应用于企业决策支持。本文深入解析了BI的重要性、演进历程,并探讨企业是否真正具备实施BI的条件,帮助读者理性评估需求,避免盲目跟风。
登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问