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

news2024/9/29 23:32:44

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

准备工作

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

然后我们其他的.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;
}

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

#Linux(Samba安装)

&#xff08;一&#xff09;发行版&#xff1a;Ubuntu16.04.7 &#xff08;二&#xff09;记录&#xff1a; &#xff08;1&#xff09;键入命令安装Samba sudo apt-get install samba &#xff08;2&#xff09;修改samba配置文件 //打开配置文件 sudo vi /etc/samba/smb.…

GPT4.0

GPT4.0 支持官网所有功能以及所有第三方GPTS&#xff0c;完全同步官网。无需魔法&#xff0c;填写授权码直达官网。全天超18小时维护&#xff0c;无需担心不稳定。没有永久卡&#xff0c;3.5免费提供&#xff0c;4.0可以按需下单即可&#xff0c;不存在跑路。 需要的联系

【办公类-16-07-07】“2023下学期 中班户外游戏2(有场地和无场地版,每天不同场地)”(python 排班表系列)

作品展示 背景需求&#xff1a; 2024年2月教务组发放的是“每周五天内容相同&#xff0c;两周10天内容相同”的户外游戏安排 【办公类-16-07-05】合并版“2023下学期 大班户外游戏&#xff08;有场地和无场地版&#xff0c;两周一次&#xff09;”&#xff08;python 排班表系…

机器学习基础知识面经(个人记录)

朴素贝叶斯 特征为理想状态下的独立同分布&#xff0c;作为机器学习的重要基石和工具 由贝叶斯公式推导而来 是后验概率&#xff1a;在B发生的条件下A发生的概率。 是似然概率: 在 发生的条件下 发生的概率。 是先验概率: 发生的概率&#xff0c;而不考虑 的影响。 是…

Git工具的详细使用

一、环境说明 [rootgit ~]# getenforce Disabled [rootgit ~]# systemctl status firewalld ● firewalld.service - firewalld - dynamic firewall daemonLoaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)Active: inactive (d…

LeetCode-热题100:42. 接雨水

题目描述 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 1&#xff1a; 输入&#xff1a; height [0,1,0,2,1,0,1,3,2,1,2,1] 输出&#xff1a; 6 解释&#xff1a; 上面是由数组 [0,1,0,2,1,…

地宫取宝dfs

分析&#xff1a; 矩阵里的每一个位置都有标记&#xff0c;要求的问题是&#xff1a;有几种方法能完成这个规定。 那么&#xff0c;我们只需要计算从开始(1,1)到最后(n,m)的深度优先搜索中&#xff0c;有几个是满足要求的即为正确答案。 有个要求是&#xff0c;如果一个格子中…

Verilog刷题笔记44

题目&#xff1a;Consider the n-bit shift register circuit shown below: 解题&#xff1a; module top_module (input clk,input w, R, E, L,output Q );always(posedge clk)beginif(L1)Q<R;elseQ<(E1)?w:Q;endendmodule结果正确&#xff1a; 注意点&#xff1a; …

【每日力扣】332. 重新安排行程与51. N 皇后

&#x1f525; 个人主页: 黑洞晓威 &#x1f600;你不必等到非常厉害&#xff0c;才敢开始&#xff0c;你需要开始&#xff0c;才会变的非常厉害。 332. 重新安排行程 给你一份航线列表 tickets &#xff0c;其中 tickets[i] [fromi, toi] 表示飞机出发和降落的机场地点。请你…

鸿蒙Harmony应用开发—ArkTS-枚举说明

说明&#xff1a; 本模块首批接口从API version 7开始支持&#xff0c;后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 Color 从API version 9开始&#xff0c;该接口支持在ArkTS卡片中使用。 颜色名称颜色值颜色示意Black0x000000 Blue0x0000ff Brown…

Elsevier(爱思唯尔)如何查询特刊special issue

1. 以Knowledge-Based Systems为例 网站&#xff1a;https://www.sciencedirect.com/journal/knowledge-based-systems 2.具体位置

数据结构面试常见问题之串的模式匹配(KMP算法)系列-简单解决方案

&#x1f600;前言 字符串匹配是计算机科学中一个常见的问题&#xff0c;指的是在一个长字符串中查找一个短字符串的出现位置。在文本编辑、生物信息学、数据挖掘等领域都有着广泛的应用。 本文将介绍 KMP 算法&#xff0c;一种用于解决字符串匹配问题的经典算法。KMP 算法可以…

向开发板上移植ip工具:交叉编译 ip工具

一. 简介 前面几篇文章学习了 CAN设备节点的创建&#xff0c;以及如何使能 CAN驱动。 本文学习向开发板上移植ip工具。 二. 向开发板上移植ip工具&#xff1a;交叉编译 ip工具 1. 移植ip工具的原因 开发板加载的文件系统&#xff08;即之前我使用 busybox工具制作的root…

Go --- 编程知识点及其注意事项

new与make 二者都是用于内存分配&#xff0c;当声明的变量是引用类型时&#xff0c;不能给该变量赋值&#xff0c;因为没有分配空间。 我们可以用new和make对其进行内存分配。 首先说说new new函数定义 func new(Type) *Type传入一个类型&#xff0c;返回一个指向分配好该…

C++例子

#include<iostream> using namespace std;//抽象类 //抽象cpu类 class CPU { public:virtual void calcuate()0; }; //抽象显卡类 class VideoCard { public:virtual void display()0; }; //抽象内存条类 class Memory { public:virtual void storage()0;};//电脑类 clas…

vue3+ts+vite axios封装请求并扩展入参

requset.ts import axios, { AxiosResponse } from axios import { getToken, removeToken } from /utils/auth// 创建axios实例 const service axios.create({baseURL: , // 所有的请求地址前缀部分(没有后端请求不用写)timeout: 60000 // 请求超时时间(毫秒)// withCredent…

LeetCode---389周赛

题目列表 3083. 字符串及其反转中是否存在同一子字符串 3084. 统计以给定字符开头和结尾的子字符串总数 3085. 成为 K 特殊字符串需要删除的最少字符数 3086. 拾起 K 个 1 需要的最少行动次数 一、字符串及其反转中是否存在同一子字符串 直接暴力枚举即可&#xff0c;代码…

Linux(Centos)安装mysql 8 并且使用systemctl管理服务

1.下载mysql包 地址 MySQL :: Download MySQL Community Server (Archived Versions) 注&#xff1a;下载我圈住的减压之后里面会有tar.gz 再次减压才会是软件主体 2.安装和准备 yum -y install numactl 安装numactl tar -xvf mysql-8.0.30-el7-x86_64.tar 拆分 …

算法思想总结:位运算

创作不易&#xff0c;感谢三连支持&#xff01;&#xff01; 一、常见的位运算总结 标题 二、位1的个数 . - 力扣&#xff08;LeetCode&#xff09; 利用第七条特性&#xff1a;n&&#xff08;n-1&#xff09;干掉最后一个1&#xff0c;然后每次都用count去统计&#xff…

目标检测——PP-YOLOv2算法解读

PP-YOLO系列&#xff0c;均是基于百度自研PaddlePaddle深度学习框架发布的算法&#xff0c;2020年基于YOLOv3改进发布PP-YOLO&#xff0c;2021年发布PP-YOLOv2和移动端检测算法PP-PicoDet&#xff0c;2022年发布PP-YOLOE和PP-YOLOE-R。由于均是一个系列&#xff0c;所以放一起解…