用顺序表实现通讯录

前言

       这次的通讯录是基于上一篇的动态顺序表的基础上实现的,如果对动态顺序表不熟悉,可以打开这个链接阅读http://t.csdnimg.cn/9zJ5g,这里我们会调用动态顺序表的函数。
如果想看静态顺序表实现通讯录,可以打开这个链接阅读http://t.csdnimg.cn/iC4a6

代码最终的效果图

现在我来带大家实现一下~~

Contact.h

       在创建通讯录的时候,我们需要定义一个结构体来保存用户信息。

#define MAX_NAME 20
#define MAX_GENDER 10
#define MAX_TELE 20
#define MAX_ADDR 50

typedef struct PeopleInformation
{
	char name[MAX_NAME];
	char gender[MAX_GENDER];
	int age;
	char tele[MAX_TELE];
	char addr[MAX_ADDR];
}PeoInfo;

       由于后续的函数实现是通讯录基于顺序表来实现的,所以我们的通讯录需要使用到顺序表的一些接口函数,为了凸显通讯的特点,我们可以使用contact来重新定义顺序表的名字,这里使用前置声明。

typedef struct SeqList contact;

我们实现通讯录是基于顺序表,所以我们在顺序表添加Contact.h这个头文件。
由于上面我们提到,要使用contact来重新定义顺序表的名字,我们不能直接使用SL,是因为我们的Contact.h是没有包含SeqList.h的,而且也不能包含(两个头文件是不能相互包含的,否则会发生冲突,编译器会报错),由于没有包含SeqList.h,所以只能使用struct SeqList来进行外置声明。

通讯录函数的实现

初始化和导入上回的数据

       如果上次的通讯录是由数据的,我们可以导入进来,这里使用了文件操作函数。

void PushContact(contact* con)
{
	FILE* pf = fopen("contact.txt", "rb");
	if (pf == NULL)
	{
		printf("未导入上次的通讯录的数据\n");
		return;
	}
	int i = 0;
	int ret = 0;
	while (1)
	{
		SLCheckCapacity(con);
		ret = fread(&con->data[i], sizeof(PeoInfo), 1, pf);
		if (ret == 0)
		{
			break;
		}
		con->size++;
		i++;
	}
	
	fclose(pf);
	pf = NULL;
}

我们在进行初始化的时候,进行初始化,再导入上次通讯录的数据。

void InitContact(contact* con)
{
	SLInit(con);
	PushContact(con);
}

销毁和保存数据

在销毁通讯录(将内存的通讯录数据清空)之前,我们可以将内存中储存的数据先保留在文件中,方便下次使用。

void DestroyContact(contact* con)
{
	SaveContact(con);
	SLDestroy(con);
}

还是要使用文件操作函数来保留数据:

void SaveContact(contact* con)
{
	FILE* pf = fopen("contact.txt", "wb");
	if (pf == NULL)
	{
		perror("fopen");
		return;
	}

	int i = 0;
	for (i = 0; i < con->size; i++)
	{
		fwrite(&con->data[i], sizeof(PeoInfo), 1, pf);
	}

	fclose(pf);
	pf = NULL;

	printf("已保存好通讯录!\n");
}

添加数据

顺序表有三个插入函数,大家可以自由发挥,这里我调用了尾插函数。

void AddContact(contact* con)
{
	PeoInfo tmp;
	printf("请输入添加人的姓名:");
	scanf("%s", tmp.name);

	printf("请输入添加人的性别:");
	scanf("%s", tmp.gender);

	printf("请输入添加人的年龄:");
	scanf("%d", &tmp.age);

	printf("请输入添加人的电话:");
	scanf("%s", tmp.tele);

	printf("请输入添加人的地址:");
	scanf("%s", tmp.addr);

	//采用尾插
	SLPushBack(con, tmp);

	printf("添加成功\n");
}

删除数据

顺序表有三个删除函数,大家可以自由发挥,这里我调用了尾删函数。

void DelContact(contact* con)
{
	//采用尾删
	SLPopBack(con);
	printf("删除成功\n");
}

展示数据

void ShowContact(contact* con)
{
	assert(con);
	int i = 0;
	if (con->size == 0)
	{
		printf("通讯录为空\n");
		return;
	}

	printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");
	for (i = 0; i < con->size; i++)
	{
		printf("%s %s %d %s %s\n", con->data[i].name, 
									con->data[i].gender, 
									con->data[i].age,
									con->data[i].tele, 
									con->data[i].addr);
	}
	printf("\n");
}

这里我先判断了一下通讯录是否有数据,有我才打印,没有我就提示一下。

查找数据

这里的通讯录结构体包含姓名、性别、年龄、电话和地址,我这里是通过姓名来查找的,这里大家可以自由发挥。

要注意姓名查找是字符串进行比较,需要调用strcmp函数,也就是需要用到string.h这个头文件,需要包含一下这个头文件。

void FindContact(contact* con)
{
	char name[MAX_NAME];
	printf("输入你要查找的姓名:");
	scanf("%s", name);

	int find = SLFind(con, name);
	if (find >= 0)
	{
		printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");
		printf("%s %s %d %s %s\n", con->data[find].name,
			con->data[find].gender,
			con->data[find].age,
			con->data[find].tele,
			con->data[find].addr);
	}
	else
	{
		printf("查无此人\n");
	}
	printf("\n");
}

修改数据

这里的修改数据我是先通过查找你要修改的名字找到对应的数据,再进行修改,这里大家也可以自由发挥。

void ModifyContact(contact* con)
{
	char name[MAX_NAME];
	printf("输入你要修改的姓名:");
	scanf("%s", name);

	int find = SLFind(con, name);
	if (find < 0)
	{
		printf("此人不存在\n");
		return;
	}

	printf("请输修改人的姓名:");
	scanf("%s", con->data[find].name);

	printf("请输入修改人的性别:");
	scanf("%s", con->data[find].gender);

	printf("请输入修改人的年龄:");
	scanf("%d", &con->data[find].age);

	printf("请输入修改人的电话:");
	scanf("%s", con->data[find].tele);

	printf("请输入修改人的地址:");
	scanf("%s", con->data[find].addr);

	printf("修改成功\n");
}

菜单实现

       写完上述程序之后,我们就可以进行封装了,我们可以写一个简易的小菜单来提供选择,让用户自行使用。

void menu()
{
	printf("***********          欢迎来到通讯录         ***********\n");
	printf("***********   1.增加联系人   2.删除联系人   ***********\n");
	printf("***********   3.查找联系人   4.修改联系人   ***********\n");
	printf("***********   5.展示通讯录   0.退出通讯录   ***********\n");
	printf("*******************************************************\n");
}

接着我们来实现主程序实现通讯录这个小程序

int main()
{
	int option = 0;
	contact peo;
	InitContact(&peo);
	do
	{
		menu();
		printf("请选择:");
		scanf("%d", &option);
		switch (option)
		{
		case 1:
			AddContact(&peo);
			break;
		case 2:
			DelContact(&peo);
			break;
		case 3:
			FindContact(&peo);
			break;
		case 4:
			ModifyContact(&peo);
			break;
		case 5:
			ShowContact(&peo);
			break;
		case 0:
			printf("退出通讯录\n");
			DestroyContact(&peo);
			break;
		default:
			printf("输入错误!\n");
			break;
		}

	} while (option);
	return 0;
}

最终是代码

Contact.h

#pragma once

#define MAX_NAME 20
#define MAX_GENDER 10
#define MAX_TELE 20
#define MAX_ADDR 50

typedef struct PeopleInformation
{
	char name[MAX_NAME];
	char gender[MAX_GENDER];
	int age;
	char tele[MAX_TELE];
	char addr[MAX_ADDR];
}PeoInfo;

//前置声明
typedef struct SeqList contact;

//初始化通讯录
void InitContact(contact* con);

//添加通讯录数据
void AddContact(contact* con);

//删除通讯录数据
void DelContact(contact* con);

//展示通讯录数据
void ShowContact(contact* con);

//查找通讯录数据
void FindContact(contact* con);

//修改通讯录数据
void ModifyContact(contact* con);

//销毁通讯录数据
void DestroyContact(contact* con);

//保存通讯录的数据
void SaveContact(contact* con);

//导入上次的通讯录的数据
void PushContact(contact* con);

SeqList.h

#pragma once

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "Contact.h"
#include <string.h>

typedef PeoInfo SLDataType;
#define MAX_CAPACITY 4

typedef struct SeqList
{
	SLDataType* data;
	int size;
	int capacity;
}SL;

void SLInit(SL* ps);//顺序表初始化
void SLDestroy(SL* ps);//顺序表销毁

//插入
void SLPushBack(SL* ps, SLDataType x);//尾插

//删除
void SLPopBack(SL* ps);//尾删

//扩容
void SLCheckCapacity(SL* ps);

//查找
int SLFind(SL* ps, char* x);

Contact.c

#include "SeqList.h"

//初始化通讯录
void InitContact(contact* con)
{
	SLInit(con);
	PushContact(con);
}

//销毁通讯录数据
void DestroyContact(contact* con)
{
	SaveContact(con);
	SLDestroy(con);
}

//添加通讯录数据
void AddContact(contact* con)
{
	PeoInfo tmp;
	printf("请输入添加人的姓名:");
	scanf("%s", tmp.name);

	printf("请输入添加人的性别:");
	scanf("%s", tmp.gender);

	printf("请输入添加人的年龄:");
	scanf("%d", &tmp.age);

	printf("请输入添加人的电话:");
	scanf("%s", tmp.tele);

	printf("请输入添加人的地址:");
	scanf("%s", tmp.addr);

	//采用尾插
	SLPushBack(con, tmp);

	printf("添加成功\n");
}

//展示通讯录数据
void ShowContact(contact* con)
{
	assert(con);
	int i = 0;
	if (con->size == 0)
	{
		printf("通讯录为空\n");
		return;
	}

	printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");
	for (i = 0; i < con->size; i++)
	{
		printf("%s %s %d %s %s\n", con->data[i].name, 
									con->data[i].gender, 
									con->data[i].age,
									con->data[i].tele, 
									con->data[i].addr);
	}
	printf("\n");
}

//删除通讯录数据
void DelContact(contact* con)
{
	//采用尾删
	SLPopBack(con);
	printf("删除成功\n");
}

//查找通讯录数据
void FindContact(contact* con)
{
	char name[MAX_NAME];
	printf("输入你要查找的姓名:");
	scanf("%s", name);

	int find = SLFind(con, name);
	if (find >= 0)
	{
		printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");
		printf("%s %s %d %s %s\n", con->data[find].name,
			con->data[find].gender,
			con->data[find].age,
			con->data[find].tele,
			con->data[find].addr);
	}
	else
	{
		printf("查无此人\n");
	}
	printf("\n");
}

//修改通讯录数据
void ModifyContact(contact* con)
{
	char name[MAX_NAME];
	printf("输入你要修改的姓名:");
	scanf("%s", name);

	int find = SLFind(con, name);
	if (find < 0)
	{
		printf("此人不存在\n");
		return;
	}

	printf("请输修改人的姓名:");
	scanf("%s", con->data[find].name);

	printf("请输入修改人的性别:");
	scanf("%s", con->data[find].gender);

	printf("请输入修改人的年龄:");
	scanf("%d", &con->data[find].age);

	printf("请输入修改人的电话:");
	scanf("%s", con->data[find].tele);

	printf("请输入修改人的地址:");
	scanf("%s", con->data[find].addr);

	printf("修改成功\n");
}

//保存通讯录的数据
void SaveContact(contact* con)
{
	FILE* pf = fopen("contact.txt", "wb");
	if (pf == NULL)
	{
		perror("fopen");
		return;
	}

	int i = 0;
	for (i = 0; i < con->size; i++)
	{
		fwrite(&con->data[i], sizeof(PeoInfo), 1, pf);
	}

	fclose(pf);
	pf = NULL;

	printf("已保存好通讯录!\n");
}

//导入上次的通讯录的数据
void PushContact(contact* con)
{
	FILE* pf = fopen("contact.txt", "rb");
	if (pf == NULL)
	{
		printf("未导入上次的通讯录的数据\n");
		return;
	}
	int i = 0;
	int ret = 0;
	while (1)
	{
		SLCheckCapacity(con);
		ret = fread(&con->data[i], sizeof(PeoInfo), 1, pf);
		if (ret == 0)
		{
			break;
		}
		con->size++;
		i++;
	}
	
	fclose(pf);
	pf = NULL;
}

SeqList.c

#include"SeqList.h"

void SLInit(SL* ps)//顺序表初始化
{
	ps->data = NULL;
	ps->size = ps->capacity = 0;
}

void SLDestroy(SL* ps)//顺序表销毁
{
	assert(ps);
	free(ps->data);
	ps->data = NULL;
	ps->size = ps->capacity = 0;
}

//插入
void SLPushBack(SL* ps, SLDataType x)//尾插
{
	assert(ps);
	SLCheckCapacity(ps);

	ps->data[ps->size++] = x;
}

//删除
void SLPopBack(SL* ps)//尾删
{
	assert(ps);
	assert(ps->size);
	ps->size--;
}

//扩容
void SLCheckCapacity(SL* ps)
{
	assert(ps);
	if (ps->size == ps->capacity)
	{
		int newcapacity = ps->capacity == 0 ? MAX_CAPACITY : ps->capacity * 2;
		SLDataType* tmp = (SLDataType*)realloc(ps->data, newcapacity * sizeof(SLDataType));
		if (tmp == NULL)
		{
			perror("realloc fail");
			exit(1);
		}
		ps->data = tmp;
		ps->capacity = newcapacity;
	}
}

//查找
int SLFind(SL* ps,  char* x)
{
	assert(ps);
	int i = 0;
	for (i = 0; i < ps->size; i++)
	{
		if (strcmp(ps->data[i].name, x) == 0)
		{
			return i;
		}
	}
	return -1;
}

test.c(主程序的实现)

#include"SeqList.h"

void menu()
{
	printf("***********          欢迎来到通讯录         ***********\n");
	printf("***********   1.增加联系人   2.删除联系人   ***********\n");
	printf("***********   3.查找联系人   4.修改联系人   ***********\n");
	printf("***********   5.展示通讯录   0.退出通讯录   ***********\n");
	printf("*******************************************************\n");
}

int main()
{
	int option = 0;
	contact peo;
	InitContact(&peo);
	do
	{
		menu();
		printf("请选择:");
		scanf("%d", &option);
		switch (option)
		{
		case 1:
			AddContact(&peo);
			break;
		case 2:
			DelContact(&peo);
			break;
		case 3:
			FindContact(&peo);
			break;
		case 4:
			ModifyContact(&peo);
			break;
		case 5:
			ShowContact(&peo);
			break;
		case 0:
			printf("退出通讯录\n");
			DestroyContact(&peo);
			break;
		default:
			printf("输入错误!\n");
			break;
		}

	} while (option);
	return 0;
}

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

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

相关文章

thinkphp6入门(21)-- 如何删除图片、文件

假设文件的位置在 /*** 删除文件* $file_name avatar/20240208/d71d108bc1086b498df5191f9f925db3.jpg*/ function deleteFile($file_name) {// 要删除的文件路径$file app()->getRootPath() . public/uploads/ . $file_name; $result [];if (is_file($file)) {if (unlin…

Vite 项目中环境变量的配置和使用

Vite 项目中环境变量的声明 我们要在 Vite 项目中进行环境变量的声明&#xff0c;那么需要在项目的根目录下&#xff0c;新建 .env.[mode] 文件用于声明环境变量&#xff0c;如&#xff1a; .env.test 文件用于测试环境下项目全局变量的声明.env.dev 文件用于开发环境下项目全…

创意绘图小程序:绘画与实用功能的完美融合

创意绘图小程序&#xff1a;绘画与实用功能的完美融合 在数字化时代&#xff0c;创意绘图小程序以其便捷性、互动性和创新性&#xff0c;成为了人们表达自我、释放创意的新平台。本文将介绍一款集白板画、黑板画功能于一身&#xff0c;同时融合画笔调整、画布清空、橡皮擦清除…

在线考试|基于Springboot的在线考试管理系统设计与实现(源码+数据库+文档)

在线考试管理系统目录 目录 基于Springboot的在线考试管理系统设计与实现 一、前言 二、系统设计 三、系统功能设计 1、前台&#xff1a; 2、后台 管理员功能 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 博主…

C语言动态内存空间分配

1. 前言 在讲内存分配前&#xff0c;咱来聊一下为什么会有内存分配这个概念呢&#xff0c;大家都知道C语言当中是有着许多的数据类型&#xff0c;使用这些数据类型就会在内存上开辟其相对应的空间&#xff0c;那既然会开辟相应的空间&#xff0c;为什么还会有内存分配呢&#x…

【数据库】数据库的介绍、分类、作用和特点,AI人工智能数据如何存储

欢迎来到《小5讲堂》&#xff0c;大家好&#xff0c;我是全栈小5。 这是《数据库》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深对知识…

深度学习理论基础(三)封装数据集及手写数字识别

目录 前期准备一、制作数据集1. excel表格数据2. 代码 二、手写数字识别1. 下载数据集2. 搭建模型3. 训练网络4. 测试网络5. 保存训练模型6. 导入已经训练好的模型文件7. 完整代码 前期准备 必须使用 3 个 PyTorch 内置的实用工具&#xff08;utils&#xff09;&#xff1a; ⚫…

蓝桥杯 - 穿越雷区

解题思路&#xff1a; dfs 方法一&#xff1a; import java.util.Scanner;public class Main {static char[][] a;static int[][] visited;static int[] dx { 0, 1, 0, -1 };static int[] dy { 1, 0, -1, 0 };static long min Long.MAX_VALUE;static long count 0;publi…

先进电气技术 —— (控制理论)何为稳定性?

一、系统稳定性 在控制理论中&#xff0c;系统稳定性是一个非常关键的概念&#xff0c;它主要涉及系统对外界扰动或内部变动的响应行为。以下是与系统稳定性相关的一些核心名词及其解释&#xff1a; 基本概念 稳定性&#xff08;Stability&#xff09; 系统稳定性是指当系统受…

Autosar工具链配置 CanNM

CAN网络管理filter 网管报文范围0x600~0x6FF repeat message time 超时时间 接收到主动唤醒源&#xff0c;网管报文快发周期&#xff0c;次数&#xff1b;正常周期发送时间 网管报文btye设置&#xff1a;1、重复消息请求位设置 2、ECU地址 wait bus-sleep 定时设置以及网管报…

蓝桥杯第十四届--子树的大小

题目描述 给定一棵包含 n 个结点的完全 m 叉树&#xff0c;结点按从根到叶、从左到右的顺序依次编号。 例如下图是一个拥有 11 个结点的完全 3 叉树。 你需要求出第 k 个结点对应的子树拥有的结点数量。 输入格式 输入包含多组询问。 输入的第一行包含一个整数 T &#xf…

telnet远程管理设备

实验目的&#xff1a;通过本机管理远端设备&#xff0c;模拟本地网卡和远端设备可以通信&#xff0c;配置telnet账户&#xff0c;远程管理设备&#xff0c;不用进入机房方式 拓扑图 云朵模拟本机的网卡&#xff0c;配置ar1的g0/0/0口IP后&#xff0c;确保在同一网络&#xff0…

【正点原子探索者STM32F4】TFTLCD实验学习记录

【正点原子探索者STM32】LCD实验学习记录 硬件硬件连接软件设计变量类型定义LCD参数结构体LCD地址结构体 函数定义读写命令和数据简介6个基本函数坐标设置函数画点函数读点函数字符显示函数LCD初始化 小结参考 硬件 STM32F407、4.3寸LCD屏 硬件连接 LCD_BL(背光控制)对应 PB1…

传输层 --- TCP (上篇)

目录 1. TCP 1.1. TCP协议段格式 1.2. TCP的两个问题 1.3. 如何理解可靠性 1.4. 理解确认应答机制 2. TCP 报头中字段的分析 2.1. 序号和确认序号 2.1.1. 序号和确认序号的初步认识 2.1.2. 如何正确理解序号和确认序号 2.2. TCP是如何做到全双工的 2.3. 16位窗口大小…

Redis Desktop Manager可视化工具

可视化工具 Redis https://www.alipan.com/s/uHSbg14XmsL 提取码: 38cl 点击链接保存&#xff0c;或者复制本段内容&#xff0c;打开「阿里云盘」APP &#xff0c;无需下载极速在线查看&#xff0c;视频原画倍速播放。 官网下载&#xff08;不推荐&#xff09;&#xff1a;http…

【智能优化算法】IHAOAVOA(一种改进的混合天鹰优化算法(AO)和非洲秃鹫优化算法(AVOA))

发表在Mathematical Biosciences and Engineering的文章&#xff1a;IHAOAVOA: An improved hybrid aquila optimizer and African vultures optimization algorithm for global optimization problems.https://www.x-mol.com/paperRedirect/1572654041256222720 01.引言 天鹰…

Linux 安装系统可视化监控工具 Netdata

目录 About 监控工具 NetdataLinux 系统安装 Netdata关于 openEuler1、查看内核信息2、查看主机信息3、查看 dnf 包管理器的版本 Netdata 安装1、更新系统环境相关 rpm 包2、查看 netdata 包信息3、安装 netdata 包4、编辑 netdata.conf 配置5、启动 netdata 服务6、查看 netda…

页面静态化:Freemarker入门案例和常用指令教程

页面静态化其实就是将原来的动态网页(例如通过ajax请求动态获取数据库中的数据并展示的网页)改为通过静态化技术生成的静态网页&#xff0c;这样用户在访问网页时&#xff0c;服务器直接给用户响应静态html页面&#xff0c;没有了动态查询数据库的过程。 那么这些静态HTML页面…

TestNG Include and exclude

在这篇文章中&#xff0c;我们将详细讨论TestNG的包含和排除标签。下面是我们将在这篇文章中看到的要点- 包含和排除包第二&#xff0c;包括和排除测试方法最后&#xff0c;包括和排除组 我们只能将exclude标记与packages、methods和run标记&#xff08;groups的子标记&#…

公园景区小红书抖音打造线上流量运营策划方案

【干货资料持续更新&#xff0c;以防走丢】 公园景区小红书抖音打造线上流量运营策划方案 部分资料预览 资料部分是网络整理&#xff0c;仅供学习参考。 共70页可编辑&#xff08;完整资料包含以下内容&#xff09; 目录 公园的线上运营方案&#xff1a; 一、运营目标 1. 品…
最新文章