c语言——通讯录(文件版)

大家好我是小锋,今天我们来实现一个通讯录

准备工作

为了让我们的代码具有条理我们要建立三个文件一个文件用来放头文件一个文件用来放函数的实现,一个文件用来实现通讯录的基本逻辑。

然后我们其他的.c文件要使用头文件时我们要用# include<tongxunlu.h>包含;

接下来我们来讲讲基本逻辑,首先通讯录要完成的功能大致有哪些?

我们是不是要先建立一个界面让人选择这些功能?

选择上面功能我们就实现什么功能我们是不是要用到switch语句来实现,功能选择又不是只选一次,所以我们还要在外面嵌套循环,我们不论如何都要进行选择所以我们应该用do while循环。

这么看主体逻辑是不是有了?

我们的通讯录要存储联系人的各种信息,所以我们要创建一个结构体变量来存储这些信息

我们的通讯录要存储多少个人的信息我们不知道所以我们可以动态开辟内存当内存不够是我们可以开辟内存所以我们再创建一个通讯录结构体变量

接下来我们在main函数中就可以创建一个可以动态开辟内存的通讯录了

接下来我们肯定要初始化通讯录

接下来我们一一实现通讯录的功能

增加联系人

这里主要注意的是内存够不够,

我们写了一个函数来判断内存

显示联系人

这个很容易实现一个循环就搞定了

删除联系人

这里我们首先要判断删除的人存不存在,存在我们才进行删除。

这里删除我们就用后一块空间覆盖前一块空间并且删除之后存储的人变少了,我们记录人数的变量要减一。

修改联系人

与删除差不多先判断有没有这个人再进行修改。

查找联系人

这里我们发现有多个函数都要进行查找操作我们可以把这个功能分装成一个函数

排序联系人

最后的排序我们可以用qsort函数实现。

接下来我们还有退出函数还未实现,如果我们直接退出通讯录中的数据是不是销毁了,所以我们把通讯录的信息写入文件中,这样我们再次打开通讯录时,再从初始化中读取出来

最后我们再将动态开辟的内存销毁

这样一个通讯录就写成了。

源代码如下

tongxunlu.h

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<errno.h>

#define NAME 20
#define PHONE 13
#define WHTER 20
#define MAN 5
#define MAX 100

# define MRRL 3
# define MRKR 2


//联系人的信息
typedef struct people {
	char mingzi[NAME];
	int nianling;
	char dianhua[PHONE];
	char dizhi[WHTER];
	char xingbie[MAN];
}people;

//静态通讯录
//typedef struct tongxunlu {
//	people date[MAX];
//	int yicun;
//}tongxunlu;
//动态通讯录
typedef struct tongxunlu {
	people* date;
	int yicun;//存储联系人个数
	int RL;//容量
}tongxunlu;



//初始化通讯录
void chushihua(tongxunlu* lgf);


//增加联系人
void Zjia(tongxunlu* lgf);

//显示联系人
void Xshi(const tongxunlu* lgf);

//删除联系人
void Schu(tongxunlu* lgf);

//修改联系人
void Xgai(tongxunlu* lgf);

//查找联系人
void Czhao(const tongxunlu* lgf);

//排序联系人
void Pxu(tongxunlu* lgf);

//释放内存
void Sneicun(tongxunlu* lgf);

//文件保存
void wenjian(tongxunlu* lgf);

tongxunlu.c

# include"wenjian.h"


//扩容
void pand(tongxunlu* lgf) {
	if (lgf->yicun == lgf->RL) {
		printf("容量不足——扩容\n");
		people* ps = (people*)realloc(lgf->date, (lgf->RL + MRKR) * sizeof(people));
		if (ps == NULL) {
			printf("扩容失败:%s\n", strerror(errno));
			return;
		}
		lgf->date = ps;
		lgf->RL += MRKR;
		printf("扩容成功,当前容量为%d\n", lgf->RL);
	}
}




//查找对象
int chazhao(tongxunlu* lgf, char* add) {
	int i = 0;
	for (i = 0; i < lgf->yicun; i++) {
		int n = strcmp(lgf->date[i].mingzi, add);
		if (n == 0) {
			return i;
		}
	}
	return -1;
}



//初始化通讯录
//void chushihua(tongxunlu* lgf) {
//	lgf->yicun = 0;
//	memset(lgf->date, 0, sizeof(lgf->date));
//}





//动态通讯录初始化
void chushihua(tongxunlu* lgf) {
	lgf->date = (people*)malloc(MRRL * sizeof(people));
	if (lgf->date == NULL) {
		printf("开辟内存失败:%s\n", strerror(errno));
		return;
	}
	memset(lgf->date, 0, MRRL * sizeof(people));
	lgf->RL = MRRL;
	lgf->yicun = 0;

	//读取文件
	//打开文件
	FILE* pa = fopen("tongxunlu.txt", "rb");
	if (pa == NULL) {
		perror("fopen");
		return ;
	}
	people mon;
	//读文件
	while (fread(&mon, sizeof(people), 1, pa)) {
		pand(lgf);
		lgf->date[lgf->yicun] = mon;
		lgf->yicun++;
	}
	fclose(pa);
	pa = NULL;
}



//静态版本
//增加联系人
//void Zjia(tongxunlu* lgf) {
//	//判断通讯录是否满人
//	if (lgf->yicun == 100) {
//		printf("通讯录已满,无法添加\n");
//		return;
//	}
//	//输入联系人
//	printf("请输入名字\n");
//	scanf("%s", &(lgf->date[lgf->yicun].mingzi));
//	printf("请输入年龄\n");
//	scanf("%d", &(lgf->date[lgf->yicun].nianling));
//	printf("请输入电话\n");
//	scanf("%s", &(lgf->date[lgf->yicun].dianhua));
//	printf("请输入性别\n");
//	scanf("%s", &(lgf->date[lgf->yicun].xingbie));
//	printf("请输入地址\n");
//	scanf("%s", &(lgf->date[lgf->yicun].dizhi));
//	//
//	lgf->yicun++;
//	printf("添加成功\n");
//}


//动态开辟版本
void Zjia(tongxunlu* lgf) {
	//判断通讯录是否满人

	pand(lgf);
	//输入联系人
	printf("请输入名字\n");
	scanf("%s", &(lgf->date[lgf->yicun].mingzi));
	printf("请输入年龄\n");
	scanf("%d", &(lgf->date[lgf->yicun].nianling));
	printf("请输入电话\n");
	scanf("%s", &(lgf->date[lgf->yicun].dianhua));
	printf("请输入性别\n");
	scanf("%s", &(lgf->date[lgf->yicun].xingbie));
	printf("请输入地址\n");
	scanf("%s", &(lgf->date[lgf->yicun].dizhi));
	//
	lgf->yicun++;
	printf("添加成功\n");
}




//显示联系人
void Xshi(const tongxunlu* lgf) {
	printf("%-10s %-5s %-10s %-5s %-10s\n", "名字", "年龄", "电话", "性别", "地址");
	//输出联系人
	for (int i = 0; i < lgf->yicun; i++) {
		printf("%-10s %-5d %-10s %-5s %-10s\n",
			lgf->date[i].mingzi,//名字
			lgf->date[i].nianling,//年龄
			lgf->date[i].dianhua,//电话
			lgf->date[i].xingbie,//性别
			lgf->date[i].dizhi);//地址
	}

}


//删除联系人
void Schu(tongxunlu* lgf) {
	//输入删除对象
	char* add[MAX];
	printf("请输入要删除人的名字\n");
	scanf("%s", &add);
	//查找删除对象
	int n = chazhao(lgf, add);
	if (n == -1) {
		printf("你要删除的人不存在\n");
	}
	else {
		for (int j = n; j < lgf->yicun - 1; j++) {
			lgf->date[j] = lgf->date[j + 1];
		}
		lgf->yicun--;
		printf("删除完成\n");
	}
}




//修改联系人
void Xgai(tongxunlu* lgf) {
	char add[MAX];
	//输入修改对象名字
	printf("输入修改对象名字\n");
	scanf("%s", &add);
	//查找对象
	int n = chazhao(lgf, add);
	if (n == -1) {
		printf("修改对象不存在\n");
	}
	else {
		//输入修改信息
		printf("请输入名字\n");
		scanf("%s", &(lgf->date[n].mingzi));
		printf("请输入年龄\n");
		scanf("%d", &(lgf->date[n].nianling));
		printf("请输入电话\n");
		scanf("%s", &(lgf->date[n].dianhua));
		printf("请输入性别\n");
		scanf("%s", &(lgf->date[n].xingbie));
		printf("请输入地址\n");
		scanf("%s", &(lgf->date[n].dizhi));
		printf("修改成功\n");

	}
}



//查找联系人
void Czhao(const tongxunlu* lgf) {
	char* add[MAX];
	//输入查找对象
	printf("请输入查找对象名字\n");
	scanf("%s", add);
	int n = chazhao(lgf, add);
	if (n == -1) {
		printf("查找对象不存在\n");
	}
	else {
		printf("%-10s %-5s %-10s %-5s %-10s\n", "名字", "年龄", "电话", "性别", "地址");
		printf("%-10s %-5d %-10s %-5s %-10s\n",
			lgf->date[n].mingzi,//名字
			lgf->date[n].nianling,//年龄
			lgf->date[n].dianhua,//电话
			lgf->date[n].xingbie,//性别
			lgf->date[n].dizhi);//地址
		printf("查找完成\n");
	}
}

//比较函数
int my_bijiao(const people* arr, const people* add) {
	return strcmp(arr, add);

}

//排序联系人
void Pxu(tongxunlu* lgf) {
	qsort(lgf->date, lgf->yicun, sizeof(lgf->date[0]), my_bijiao);
	printf("排序完成\n");
	Xshi(lgf);
}




//释放内存
void Sneicun(tongxunlu* lgf) {
	free(lgf->date);
	lgf->date = NULL;
	lgf->RL = 0;
	lgf->yicun = 0;
	printf("释放内存\n");
}



//文件保存
void wenjian(tongxunlu* lgf) {
	//打开文件
	FILE* ps = fopen("tongxunlu.txt", "wb");
	if (ps == NULL) {
		perror("fopen");
		return;
	}
	//写文件
	fwrite(lgf->date, sizeof(people), lgf->yicun, ps);
	//关闭文件
	fclose(ps);
	ps = NULL;
	printf("保存成功\n");
}

test.c

# include "wenjian.h"


void fm() {
	printf("————————————————————————\n");
	printf("1,增加联系人\n");
	printf("2,删除联系人\n");
	printf("3,修改联系人\n");
	printf("4,显示联系人\n");
	printf("5,排序联系人\n");
	printf("6,查找联系人\n");
	printf("0,退出通讯录\n");
	printf("————————————————————————\n");
}

enum add {
	tuichu,
	zhenjia,
	sanchu,
	xiugai,
	xianshi,
	paixu,
	chazhao,
};

int main() {
	int n = 0;
	tongxunlu lgf;
	//初始化通讯录
	chushihua(&lgf);
	do {
		fm();
		printf("请选择——》");
		scanf_s("%d", &n);
		switch (n) {
		case zhenjia:
			Zjia(&lgf);
			break;
		case sanchu:
			Schu(&lgf);
			break;
		case xiugai:
			Xgai(&lgf);
			break;
		case xianshi:
			Xshi(&lgf);
			break;
		case paixu:
			Pxu(&lgf);
			break;
		case chazhao:
			Czhao(&lgf);
			break;
		case tuichu:
			wenjian(&lgf);
			Sneicun(&lgf);
			printf("退出通讯录\n");
			break;
		default:
			printf("选择错误\n");
		}
	} while (n);
	return 0;
}

 以上就是全部内容了,如果有错误或者不足的地方欢迎大家给予建议。 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一笔画--PTA

文章目录 题目描述思路AC代码 题目描述 输入样例1 3 2 1 2 2 3 输出样例1 Y输入样例2 4 3 1 2 1 3 1 4 输出样例2 N输入样例3 1 0 输出样例3 Y思路 dfs 、欧拉通路、欧拉回路的判定 前导知识 欧拉通路、欧拉回路、欧拉图 无向图&#xff1a; ①设G是连通无向图&#xff0c;则称…

pycharm免费下载安装教程

pycharm下载地址 Download PyCharm: The Python IDE for data science and web development by JetBrains 1.进入官网之后可以下拉到最底下&#xff0c;可以设置一下所属地是中国大陆&#xff08;China Mainland)&#xff0c;这样在安装的时候展示的就是中文。 2.设置好语言之…

一个单生产-多消费模式下无锁方案(ygluu/卢益贵)

一个单生产-多消费模式下无锁方案 ygluu/卢益贵 关键词&#xff1a;生产者-消费者模型、无锁队列、golang、RWMutex 本文介绍一个“单生产(低频)-多消费”模式下的无锁哈希类方案&#xff0c;这个方案的性能优于golang的RWMutex&#xff0c;因为它永远不会因为“写”而导致与…

Java代码基础算法练习-数位交换-2024.03.23·

任务描述&#xff1a; 输入一个三位整数&#xff0c;将其个位和百位交换后输出 任务要求&#xff1a; package march0317_0331;import java.util.Scanner;public class m240323 {public static void main(String[] args) {Scanner scanner new Scanner(System.in);System.out…

家用路由器和企业路由器的区别?

一、家用路由器 家用路由器路由器交换机 它只有一个WAN口和一个LAN口&#xff0c;WAN口接公网一个地址&#xff0c;LAN口接你电脑一个IP地址&#xff0c;完全符合路由器的设计&#xff0c;而因为家里如果用了&#xff0c;说明要接多个电脑&#xff0c;那么如果还需要对每个接口…

查立得源码如何去除版权

最近发现很多人百度&#xff1a;查立得源码如何去除版权。 每个源代码/软件都是有版权的&#xff0c;无法去除&#xff0c;我们也得尊重知识产权/劳动成果。 可以去除/修改的是&#xff1a;页面显示的版权信息,查立得底部信息均可自定义(一般conn.php可修改)。 另&#xff1…

FFmepg--AVFilter过滤器使用以及yuv视频裁剪

文章目录 AVFilter 流程:api核心代码变量yuv视频裁剪AVFilter 流程: ⾸先使⽤split滤波器将input流分成两路流(main和tmp),然后分别对两路流进⾏处理。对于tmp流,先经过crop滤波器进⾏裁剪处理,再经过flip滤波器进⾏垂直⽅向上的翻转操作,输出的结果命名为flip流。再将…

浮点数在内存中的存储

目录 一.回顾&#xff1a;整数在内存中的存储 二.大小端字节序和字节序的判断 什么是大小端 &#xff1f; 为什么需要有大小端之分呢&#xff1f; 判断当前机器的字节序 三.练习 四.浮点数在内存中的存储 数字M 数字E 浮点数取的过程 E不全为0或者E不全为1 E全为0 E…

Spring Cloud二:核心组件解析

在微服务架构中&#xff0c;Spring Cloud凭借其强大的组件集合&#xff0c;为开发者提供了从服务注册与发现、负载均衡、服务调用到分布式跟踪与日志等全方位的支持。本文将深入解析Spring Cloud的核心组件&#xff0c;通过源码分析和示例代码&#xff0c;帮助读者更好地理解这…

手机实时监控电脑屏幕(手机可以看到电脑在干什么吗)

已经2024年了&#xff0c;假如你还在问我&#xff0c;手机可以看到电脑在干什么吗&#xff0c;有没有手机实时监控电脑屏幕的系统。 那么证明&#xff0c;你可能已经out 了。 现代科技告诉发展的态势下&#xff0c;这种技术已经很成熟了。 域智盾软件就可以实现这种效果↓我们…

『K8S 入门』三:资源调度

『K8S 入门』三&#xff1a;资源调度 一、Label 和 Selector 可以通过 Selector 基于 Label 匹配需要的资源 Label 标签 配置文件中&#xff08;metadata.labels&#xff09;配置 metadata: # Pod相关的元数据&#xff0c;用于描述Pod的数据name: nginx-demo #Pod的名称lab…

微信小程序使用动态ICON让小程序活起来。使用曲线救国方式,非常有效

扫码查看动画效果 当前使用的微信小程序是Skyline模式。webview一样可以使用&#xff0c;而且能更高效的直接替换URL使用。但是由于性能问题&#xff0c;建议在Skyline模式下使用&#xff01; 1、挑选喜欢的ICON 动态ICON官网&#xff1a;18,700 Animated Icons - Lordicon …

MySQL---视图

目录 一、介绍 二、语法 三、视图的更新 四、视图作用 一、介绍 视图&#xff08;View&#xff09;是一种虚拟存在的表。视图中的数据并不在数据库中实际存在&#xff0c;行和列数据来自定义视图的查询中使用的表&#xff0c;并且是在使用视图时动态生成的。 通俗的讲&#…

Stable Diffusion实现光影字效果

昨天下午有人在群里发光影图片&#xff0c;大家都觉得很酷&#xff0c;我没怎么在意。直到早上我在小红书看到有人发同款图片&#xff0c;只是一晚上的时间点赞就超过了8000&#xff0c;而且评论数也很高&#xff0c;也可以做文字定制变现。研究了一下发现这个效果不难实现&…

AbstractQueuedSynchronizer 独占式源码阅读

概述 ● 一个int成员变量 state 表示同步状态 ● 通过内置的FIFO队列来完成资源获取线程的排队工作 属性 AbstractQueuedSynchronizer属性 /*** 同步队列的头节点 */private transient volatile Node head;/*** 同步队列尾节点&#xff0c;enq 加入*/private transient …

docker 数据卷 (二)

1&#xff0c;为什么使用数据卷 卷是在一个或多个容器内被选定的目录&#xff0c;为docker提供持久化数据或共享数据&#xff0c;是docker存储容器生成和使用的数据的首选机制。对卷的修改会直接生效&#xff0c;当提交或创建镜像时&#xff0c;卷不被包括在镜像中。 总结为两…

ctfshow web入门 反序列化

254 分析代码&#xff1a; 如果用户名和密码参数都存在&#xff0c;脚本会创建一个 ctfShowUser 类的实例 $user。 接着&#xff0c;调用 $user->login($username, $password) 方法尝试登录。如果登录成功&#xff08;即用户名和密码与类中的默认值匹配&#xff09;&#…

[AutoSar]BSW_ECUC模块介绍

目录 关键词平台说明一、ECUC 的定义 关键词 嵌入式、C语言、autosar、OS、BSW 平台说明 项目ValueOSautosar OSautosar厂商vector &#xff0c; EB芯片厂商TI 英飞凌编程语言C&#xff0c;C编译器HighTec (GCC)autosar版本4.3.1 >>>>>回到总目录<<<…

iOS UIFont-新增第三方字体

背景 在项目中添加三方字体&#xff0c;是在开发中比较常见的需求&#xff0c;每次新增字体&#xff0c;都会遗忘其中某个步骤&#xff0c;又要去百度一下才能把字体添加使用成功。每次这样有点浪费时间和打击自信&#xff0c;于是便想着&#xff0c;自己好好来理一理新增字体…

Penpad 生态资产 $PDD LaunchPad 在即,Season 2 规则解读

Penpad是Scroll上的LauncPad平台&#xff0c;该平台继承了Scroll底层的技术优势&#xff0c;并基于零知识证明技术&#xff0c;推出了系列功能包括账户抽象化、灵活的挖矿功能&#xff0c;并将在未来实现合规为RWA等资产登录Scroll生态构建基础。该平台被认为是绝大多数项目、资…