通讯录文件版本

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

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;

}

目录
相关文章
|
2天前
|
人工智能 运维 安全
|
5天前
|
SpringCloudAlibaba 负载均衡 Dubbo
微服务架构下Feign和Dubbo的性能大比拼,到底鹿死谁手?
本文对比分析了SpringCloudAlibaba框架下Feign与Dubbo的服务调用性能及差异。Feign基于HTTP协议,使用简单,适合轻量级微服务架构;Dubbo采用RPC通信,性能更优,支持丰富的服务治理功能。通过实际测试,Dubbo在调用性能、负载均衡和服务发现方面表现更出色。两者各有适用场景,可根据项目需求灵活选择。
386 124
微服务架构下Feign和Dubbo的性能大比拼,到底鹿死谁手?
|
7天前
|
人工智能 JavaScript 测试技术
Qwen3-Coder入门教程|10分钟搞定安装配置
Qwen3-Coder 挑战赛简介:无论你是编程小白还是办公达人,都能通过本教程快速上手 Qwen-Code CLI,利用 AI 轻松实现代码编写、文档处理等任务。内容涵盖 API 配置、CLI 安装及多种实用案例,助你提升效率,体验智能编码的乐趣。
702 107
|
2天前
|
算法 Python
【轴承故障诊断】一种用于轴承故障诊断的稀疏贝叶斯学习(SBL),两种群稀疏学习算法来提取故障脉冲,第一种仅利用故障脉冲的群稀疏性,第二种则利用故障脉冲的额外周期性行为(Matlab代码实现)
【轴承故障诊断】一种用于轴承故障诊断的稀疏贝叶斯学习(SBL),两种群稀疏学习算法来提取故障脉冲,第一种仅利用故障脉冲的群稀疏性,第二种则利用故障脉冲的额外周期性行为(Matlab代码实现)
223 152
|
4天前
|
Java 数据库 数据安全/隐私保护
Spring 微服务和多租户:处理多个客户端
本文介绍了如何在 Spring Boot 微服务架构中实现多租户。多租户允许单个应用实例为多个客户提供独立服务,尤其适用于 SaaS 应用。文章探讨了多租户的类型、优势与挑战,并详细说明了如何通过 Spring Boot 的灵活配置实现租户隔离、动态租户管理及数据源路由,同时确保数据安全与系统可扩展性。结合微服务的优势,开发者可以构建高效、可维护的多租户系统。
203 127
|
4天前
|
Web App开发 前端开发 API
在折叠屏应用中,如何处理不同屏幕尺寸和设备类型的样式兼容性?
在折叠屏应用中,如何处理不同屏幕尺寸和设备类型的样式兼容性?
230 124
|
2天前
|
编解码 算法 自动驾驶
【雷达通信】用于集成传感和通信的OFDM雷达传感算法(Matlab代码实现)
【雷达通信】用于集成传感和通信的OFDM雷达传感算法(Matlab代码实现)
172 125
|
2天前
|
JavaScript 关系型数据库 MySQL
基于python的网上外卖订餐系统
本系统基于Python与Flask框架,结合MySQL数据库及Vue前端技术,实现了一个功能完善的网上订餐平台。系统涵盖餐品、订单、用户及评价管理模块,并深入研究订餐系统的商业模式、用户行为与服务质量。技术上采用HTML、PyCharm开发工具,支持移动端访问,助力餐饮业数字化转型。