您的位置:首页 > 新闻 > 热点要闻 > 深圳设计公司电话_搭建服务器多少钱_腾讯域名_深圳网站制作哪家好

深圳设计公司电话_搭建服务器多少钱_腾讯域名_深圳网站制作哪家好

2025/12/18 8:11:21 来源:https://blog.csdn.net/HDSTQTW/article/details/146705955  浏览:    关键词:深圳设计公司电话_搭建服务器多少钱_腾讯域名_深圳网站制作哪家好
深圳设计公司电话_搭建服务器多少钱_腾讯域名_深圳网站制作哪家好

目录

一.保存数据

二.加载文件信息到通讯录里

三.整体代码

1.test.c

 2.contact.h

3.contact.c

 


1.0,2.0版本的通讯录,运行起来的时候,可以给通讯录中增加、删除数据。此时数据是存放在内存中,当程序退出的时候,通讯录中的数据自然就不存在了。等下次运行通讯录程序的时候,数据又得重新录入,如果使用这样的通讯录就很难受。3.0版本为大家解决这一问题。

一.保存数据

我们按0退出时,不要直接销毁。应该先保存通讯录信息到文件中,再销毁。

//test.c
case EXIT://保存通讯录信息到文件中SaveContact(&con);DestroyContact(&con);printf("退出通讯录\n");
//contact.h
void SaveContact(Contact* pc);
void SaveContact(Contact* pc)
{assert(pc);//打开文件FILE* pf = fopen("contact.txt", "wb");if (NULL == pf){perror("SaveContact");}else{//写数据//关闭文件fclose(pf);pf = NULL;}
}

用 wb 形式打开文件,每次文件都是重新创建的。
比如:原来放了4个人,现在新加了2个,一共6个。下次保存时,把原来的文件清空,再把这6个重新放进去。
不会形成数据冲突、重复

fread fwrite 函数可以写1个或多个数据到文件中,用它俩。



将 ptr 指向的,要被写的 count 个,每个 size 字节的 数据,写入 FILE* (这里是 pf )指向的文件中。
返回成功写入的元素总数。


我们每次写1个数据,有多少个就写多少次。
每次要被写进文件里的是 pc->data[ i ] 。fwrite 要的是地址,pc->data[ i ] 的 地址是:pc->data + i

//contact.c
void SaveContact(Contact* pc)
{assert(pc);//打开文件FILE* pf = fopen("contact.txt", "wb");if (NULL == pf){perror("SaveContact");}else{//写数据int i = 0;for (i = 0; i < pc->sz; i++){fwrite(pc->data + i, sizeof(PeoInfo), 1, pf);}//关闭文件fclose(pf);pf = NULL;printf("保存成功\n");}
}

二.加载文件信息到通讯录里

下次运行程序,要能看到上次保存好的数据。
程序运行时,第一步就是初始化,所以我们修改它。

//动态版本  contact.c
void InitContact(Contact* pc)
{assert(pc);pc->sz = 0;PeoInfo* ptr = (PeoInfo*)calloc(DEFAULT_SZ, sizeof(PeoInfo));if (ptr == NULL){perror("InitContact:calloc");return;}pc->data = ptr;pc->capacity = DEFAULT_SZ;printf("当前联系人数量:%d\n", pc->sz);printf("当前最大容量:%d\n", pc->capacity);//加载文件信息到通讯录LoadContact(pc);
}//contact.h
void LoadContact(Contact* pc);

把数据放到 pc 指向的通讯录里。所以把 pc 传进去。


void LoadContact(Contact* pc)
{assert(pc);//打开文件FILE* pf = fopen("contact.txt", "rb");if (pf == NULL){perror("LoadContact");}else{//读数据//关闭文件fclose(pf);pf = NULL;}
}

从文件中读数据。
通讯录刚加载起来,文件里有多少个联系人我不知道。

怎么读?读到什么时候结束?看 fread 什么时候读取失败



从 FILE* (这里指 pf )指向的文件中,读取 count 个数据,每个数据 size 个字节。并将它们存储在 ptr 指定的内存块中。
返回成功读取的元素总数。


从哪个文件里读?我们清楚。

读多少个?
eg:每次读5个,如果正确读到5个,返回5 。
但有可能读不到5
eg:文件中有8个联系人,每次读5个。第一次读到5个是正常的,第二次最多读到3个就返回了,不读了。

如果 实际读到的个数 < 每次要读的个数,这就是最后一次读。
我们每次让它读一个,正常读1个返回1。读到不是一个(读取结束),返回0。放到 tmp 中

	else{//读数据PeoInfo tmp = { 0 };fread(&tmp, sizeof(PeoInfo), 1, pf);//关闭文件}

用 while 循环起来,判断条件上面分析好了。

	else{//读数据PeoInfo tmp = { 0 };int i = 0;while (fread(&tmp, sizeof(PeoInfo), 1, pf)){pc->data[i] = tmp;pc->sz++;i++;}//关闭文件}

最开始通讯录只准备好了3个空间。
假设文件里有5个联系人?要考虑扩容的问题。我们分装了函数。

void LoadContact(Contact* pc)
{assert(pc);//打开文件FILE* pf = fopen("contact.txt", "rb");if (pf == NULL){perror("LoadContact");}else{//读数据PeoInfo tmp = { 0 };int i = 0;while (fread(&tmp, sizeof(PeoInfo), 1, pf)){//扩容check_capacity(pc);pc->data[i] = tmp;pc->sz++;i++;}//关闭文件fclose(pf);pf = NULL;}
}

三.整体代码

1.test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"void menu()
{printf("************************************\n");printf("******  1. add    2. del      ******\n");printf("******  3. search 4. modify   ******\n");printf("******  5. show   6. sort     ******\n");printf("******  7. delall 0. exit     ******\n");printf("************************************\n");
}enum Option
{EXIT,//0ADD, //1DEL, //2SEARCH,MODIFY,SHOW,SORT,DELALL
};int main()
{int input = 0;//创建通讯录Contact con;//初始化通讯录InitContact(&con);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 SHOW:ShowContact(&con);break;case SORT:SortContact_ByName(&con);break;case DELALL:DelAllContact(&con);break;case EXIT://保存通讯录信息到文件中SaveContact(&con);DestroyContact(&con);printf("退出通讯录\n");break;default:printf("输入错误\n");break;}} while (input);return 0;
}

 2.contact.h

 

#pragma once
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>#define MAX 100
#define NAME_MAX 20
#define SEX_MAX 5
#define ADDR_MAX 30
#define TELE_MAX 12#define DEFAULT_SZ 3 //默认大小
#define INC_SZ 2 //每次增加
#define RED_SZ 3 //每次减少
#define DIFF_SZ_CAPA 5 //最大 - 当前 的差值//人的信息
typedef struct PeoInfo
{char name[NAME_MAX];int age;char sex[SEX_MAX];char addr[ADDR_MAX];char tele[TELE_MAX];
}PeoInfo;//动态版本
typedef struct Contact
{PeoInfo* data;//指向存放人信息的空间int sz;//当前已经存入联系人的个数int capacity;//当前通讯录的最大容量
}Contact;//初始化通讯录 -- 函数声明
void InitContact(Contact* pc);//增加联系人 -- 函数声明
void AddContact(Contact* pc);//显示通讯录中的信息 -- 函数声明
void ShowContact(const Contact* pc);//删除指定联系人
void DelContact(Contact* pc);//查找指定联系人
void SearchContact(const Contact* pc);//修改指定联系人
void ModifyContact(Contact* pc);//删除所有联系人
void DelAllContact(Contact* pc);//销毁内存空间
void DestroyContact(Contact* pc);//根据姓名排序
void SortContact_ByName(Contact* pc);//保存通讯录信息到文件中
void SaveContact(Contact* pc);//加载文件信息到通讯录里
void LoadContact(Contact* pc);

3.contact.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"//动态版本
void InitContact(Contact* pc)
{assert(pc);pc->sz = 0;PeoInfo* ptr = (PeoInfo*)calloc(DEFAULT_SZ, sizeof(PeoInfo));if (ptr == NULL){perror("InitContact:calloc");return;}pc->data = ptr;pc->capacity = DEFAULT_SZ;//加载文件信息到通讯录LoadContact(pc);
}void check_capacity(Contact* pc)
{assert(pc);if (pc->sz == pc->capacity){//扩容PeoInfo* ptr = (PeoInfo*)realloc(pc->data, (pc->capacity + INC_SZ) * sizeof(PeoInfo));if (ptr == NULL){perror("check_capacity:realloc");return;}pc->data = ptr;pc->capacity += INC_SZ;}if ((pc->capacity - pc->sz) > DIFF_SZ_CAPA){//减容PeoInfo* ptr = (PeoInfo*)realloc(pc->data, (pc->capacity - RED_SZ) * sizeof(PeoInfo));if (ptr == NULL){perror("check_capacity:realloc");return;}pc->data = ptr;pc->capacity -= RED_SZ;}
}//动态版本
void AddContact(Contact* pc)
{assert(pc);//增加一个人的信息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].addr);printf("请输入电话:");scanf("%s", pc->data[pc->sz].tele);pc->sz++;check_capacity(pc);
}void ShowContact(const Contact* pc)
{assert(pc);printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\n", "名字", "年龄", "性别", "地址", "电话");int i = 0;for (i = 0; i < pc->sz; i++){printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", pc->data[i].name,pc->data[i].age,pc->data[i].sex,pc->data[i].addr,pc->data[i].tele);}
}int FindByName(const Contact* pc, char name[])
{assert(pc);int i = 0;for (i = 0; i < pc->sz; i++){if (strcmp(pc->data[i].name, name) == 0){return i;}}return -1;
}//动态版本
void DelContact(Contact* pc)
{assert(pc);char name[NAME_MAX] = { 0 };if (pc->sz == 0){printf("通讯录为空,无法删除\n");return;}//查找printf("请输入要删除的人的名字:>");scanf("%s", name);int ret = FindByName(pc, name);if (-1 == ret){printf("要删除的人不存在\n");return;}int i = 0;//删除for (i = ret; i < pc->sz - 1; i++){pc->data[i] = pc->data[i + 1];}pc->sz--;printf("删除成功\n");check_capacity(pc);
}void SearchContact(const Contact* pc)
{assert(pc);char name[NAME_MAX] = { 0 };printf("请输入要查找人的名字:>");scanf("%s", name);int pos = FindByName(pc, name);if (-1 == pos){printf("要查找的人不存在\n");return;}//打印信息printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\n", "名字", "年龄", "性别", "地址", "电话");printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", pc->data[pos].name,pc->data[pos].age,pc->data[pos].sex,pc->data[pos].addr,pc->data[pos].tele);
}void ModifyContact(Contact* pc)
{assert(pc);char name[NAME_MAX] = { 0 };printf("请输入要修改人的名字:");scanf("%s", name);int pos = FindByName(pc, name);if (-1 == pos){printf("要修改的人不存在\n");return;}//重新录入信息printf("请输入名字:");scanf("%s", pc->data[pos].name);printf("请输入年龄:");scanf("%d", &(pc->data[pos].age));printf("请输入性别:");scanf("%s", pc->data[pos].sex);printf("请输入地址:");scanf("%s", pc->data[pos].addr);printf("请输入电话:");scanf("%s", pc->data[pos].tele);printf("修改完成\n");
}void DelAllContact(Contact* pc)
{assert(pc);pc->sz = 0;memset(pc->data, 0, sizeof(pc->data));printf("删除成功。\n");
}void DestroyContact(Contact* pc)
{assert(pc);free(pc->data);pc->data = NULL;pc->capacity = 0;pc->sz = 0;pc = NULL;
}int sortcon_byname(const void* e1, const void* e2)
{return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}void SortContact_ByName(Contact* pc)
{assert(pc);qsort(pc->data, pc->sz, sizeof(PeoInfo), sortcon_byname);printf("排序成功\n");
}void SaveContact(Contact* pc)
{assert(pc);//打开文件FILE* pf = fopen("contact.txt", "wb");if (NULL == pf){perror("SaveContact");}else{//写数据int i = 0;for (i = 0; i < pc->sz; i++){fwrite(pc->data + i, sizeof(PeoInfo), 1, pf);}//关闭文件fclose(pf);pf = NULL;printf("保存成功\n");}
}void LoadContact(Contact* pc)
{assert(pc);//打开文件FILE* pf = fopen("contact.txt", "rb");if (pf == NULL){perror("LoadContact");}else{//读数据PeoInfo tmp = { 0 };int i = 0;while (fread(&tmp, sizeof(PeoInfo), 1, pf)){//扩容check_capacity(pc);pc->data[i] = tmp;pc->sz++;i++;}//关闭文件fclose(pf);pf = NULL;}
}

 

通讯录3个版本到这里就全部实现了。

本篇的分享就到这里了,感谢观看,如果对你有帮助,别忘了点赞+收藏+关注
小编会以自己学习过程中遇到的问题为素材,持续为您推送文章。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com