实现通讯录(顺序表版本)

一、功能要求

(1)⾄少能够存储100个⼈的通讯信息

(2)能够保存⽤⼾信息:名字、性别、年龄、电话、地址等

(3)增加联系⼈信息

(4)删除指定联系⼈

(5)查找制定联系⼈

(6)修改指定联系⼈

(7)显⽰联系⼈信息

二、代码实现

所需的头文件与源文件

SeqList.h

SeqList.c  //顺序表实现

contact.h

contact.c //通讯录实现

test.c    //测试

SeqList.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include"contact.h"

// 动态顺序表 -- 按需申请

typedef PeoInfo SLDataType;
//动态顺序表
typedef struct SeqList
{
    SLDataType* arr;
    int size;     // 有效数据个数
    int capacity; // 空间容量
}SL;

//初始化
void SLInit(SL* ps);
//销毁
void SLDestroy(SL* ps);
//打印
void SLPrint(SL ps);
//扩容
void SLCheckCapacity(SL* ps);

//头部插入 / 尾部插入
void SLPushFront(SL* ps, SLDataType x);
void SLPushBack(SL* ps, SLDataType x);
//头部插删除 / 尾部删除
void SLPopFront(SL* ps);
void SLPopBack(SL* ps);

//指定位置之前插入/删除数据
void SLInsert(SL* ps, int pos, SLDataType x);
void SLErase(SL* ps, int pos);
int SLFind(SL* ps, SLDataType x);

SeqList.c

#include"SeqList.h"

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

//销毁
void SLDestroy(SL* ps)
{
	if (ps->arr)
	{
		free(ps->arr);
	}
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}

//扩容
void SLCheckCapacity(SL* ps)
{
	if (ps->capacity == ps->size)
	{
		//申请空间(增容用realloc)
		//要先判断capacity是否为零,如果为真默认给4个空间,如果为假直接乘2(三目操作符)
		int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
		SLDataType* tmp = ps->arr = (SLDataType*)realloc(ps->arr, newCapacity * sizeof(SLDataType));//要申请多大的空间
		if (tmp == NULL)
		{
			perror("realloc fail!");
			exit(1);//直接推出程序,不在继续执行
		}
		//空间申请成功
		ps->arr = tmp;
		ps->capacity = newCapacity;
	}
}

//尾插
void SLPushBack(SL* ps, SLDataType x)
{
	assert(ps);//等价于assert(ps != NULL)

	//插入数据之前要看空间够不够
	SLCheckCapacity(ps);

	//ps->arr[ps->size] = x;
	//++ps->size;
	ps->arr[ps->size++] = x;//可以一步到位也可以分两步写
}

//头插
void SLPushFront(SL* ps, SLDataType x)
{
	assert(ps);
	SLCheckCapacity(ps);
	//先让顺序表中已有的数据整体往后挪动一位
	for (int i = ps->size; i > 0; i--)
	{
		ps->arr[i] = ps->arr[i - 1];
	}
	ps->arr[0] = x;
	ps->size++;
}

//打印
void SLPrint(SL ps)
{
	for (int i = 0; i < ps.size; i++)
	{
		printf("%d ", ps.arr[i]);
	}
	printf("\n");
}

//头删
void SLPopFront(SL* ps)
{
	assert(ps);
	assert(ps->size);

	//数据整体往前挪动一位
	for (int i = 0; i < ps->size - 1; i++)
	{
		ps->arr[i] = ps->arr[i + 1];
		ps->size--;
	}
}

//尾删
void SLPopBack(SL* ps)
{
	assert(ps);
	assert(ps->size);
	//顺序表不为空
	--ps->size;
}

//在指定位置之前插入数据
void SLInsert(SL* ps, int pos, SLDataType x)
{
	assert(ps);
	assert(pos >= 0 && pos <= ps->size);
	//插入数据:空间够不够?
	SLCheckCapacity(ps);
	//让pos及以后的数据整体往后挪动一位
	for (int i = ps->size; i > pos; i--)
	{
		ps->arr[i] = ps->arr[i - 1];//arr[pos+1] = arr[pos]
	}
	ps->arr[pos] = x;
	ps->size++;
}

//删除指定位置的数据
void SLErase(SL* ps, int pos)
{
	assert(ps);
	assert(pos >= 0 && pos < ps->size);

	for (int i = pos; i < ps->size - 1; i++)
	{
		ps->arr[i] = ps->arr[i + 1];
	}
	ps->size--;
}

contact.h

#pragma once
#define NAME_MAX 100
#define SEX_MAX 4
#define TEL_MAX 11
#define ADDR_MAX 100

//前置声明

typedef struct SeqList contact;

//用户数据
//姓名 性别 年龄 电话 地址
typedef struct PersonInfo

{
	char name[NAME_MAX];
	char sex[SEX_MAX];
	int age;
	char tel[TEL_MAX];
	char addr[ADDR_MAX];

}PeoInfo;

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

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

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

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

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

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

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

contact.c

#include"contact.h"
#include"SeqList.h"

//初始化通讯录
void ContactInit(contact* con)
{
	//实际上就是顺序表的初始化
	//顺序表的初始化已经实现好了直接调用就行
	SLInit(con);
}

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

}

//添加通讯录数据
void ContactAdd(contact* con)
{
	//获取用户输入的内容:姓名 性别 年龄 电话 地址
	PeoInfo info;
	printf("请输入要添加的联系人姓名:\n");
	scanf("%s", info.name);

	printf("请输入要添加的联系人性别:\n");
	scanf("%s", info.sex);

	printf("请输入要添加的联系人年龄:\n");
	scanf("%d", &info.age);

	printf("请输入要添加的联系人电话:\n");
	scanf("%s", info.tel);

	printf("请输入要添加的联系人地址:\n");
	scanf("%s", info.addr);

	//往通讯录中添加联系人数据
	SLPushBack(con, info);
}

int FindByName(contact* con,char name[])
{
	for (int i = 0; i < con->size; i++)
	{
		if (0 == strcmp(con->arr[i].name, name))
		{
			//找到了
			return i;
		}
	}
	//没有找到
	return -1;
}


//删除通讯录数据
void ContactDel(contact* con)
{
	//要删除的数据必须存在才可以删除
	//查找
	char name[NAME_MAX];
	printf("请输入要删除的联系人姓名:\n");
	scanf("%s", name);

	int find = FindByName(con, name);
	if (find < 0)
	{
		printf("要删除的联系人数据不存在\n");
		return;
	}
	//要删除的联系人数据存在———>知道了要删除的联系人对应的下标
	SLErase(con, find);
	printf("删除成功\n");
}

//展示通讯录数据
void ContactShow(contact* con)
{
	//表头:姓名 性别 年龄 电话 地址
	printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");
	//遍历通讯录,按照打印每个联系人数据
	for (int i = 0; i < con->size; i++)
	{
		printf("%3s %2s %d %6s %s\n",
			con->arr[i].name,
			con->arr[i].sex,
			con->arr[i].age,
			con->arr[i].tel,
			con->arr[i].addr
		);
	}
}

//修改通讯录数据
void ContactModify(contact* con)
{
	//要修改的联系人数据存在
	char name[NAME_MAX];
	printf("请输入要修改的用户姓名:\n");
	scanf("%s", name);

	int find = FindByName(con, name);
	if (find < 0)
	{
		printf("要修改的联系人数据不存在\n");
		return;
	}
	//修改
	printf("请输入新的姓名\n");
	scanf("%s", con->arr[find].name);

	printf("请输入新的性别\n");
	scanf("%s", con->arr[find].sex);

	printf("请输入新的年龄\n");
	scanf("%d", &con->arr[find].age);

	printf("请输入新的电话\n");
	scanf("%s", con->arr[find].tel);

	printf("请输入新的地址\n");
	scanf("%s", con->arr[find].addr);

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

//查找通讯录数据
void ContactFind(contact* con)
{
	char name[NAME_MAX];
	printf("请输入要查找的联系人姓名:\n");
	scanf("%s", name);

	int find = FindByName(con, name);
	if (find < 0)
	{
		printf("要查找的联系人数据不存在\n");
		return;
	}
	//再次打印表格
	printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");
	printf("%3s %2s %d %6s %s\n",
		con->arr[find].name,
		con->arr[find].sex,
		con->arr[find].age,
		con->arr[find].tel,
		con->arr[find].addr
	);
}

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 op = -1;
	contact con;
	ContactInit(&con);


	do {
		menu();
		printf("请输入您的操作:\n");
		scanf("%d", &op);
		//根据不同的选择执行不同的操作
		switch (op)
		{
		case 1:
			ContactAdd(&con);
			break;
		case 2:
			ContactAdd(&con);
			break;
		case 3:
			ContactModify(&con);
			break;
		case 4:
			ContactFind(&con);
			break;
		case 5:
			ContactShow(&con);
			break;
		case 0:
			printf("退出通讯录...\n");
			break;
		default:
			printf("输入错误,请重新选择操作\n");
			break;

		}
	} while (op != 0);

	ContactDestroy(&con);
	return 0;
}

效果如图

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

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

相关文章

国内:深圳交通流量数据集

数据来源&#xff1a;深圳政府数据开放平台&#xff08;深圳市政府数据开放平台&#xff09;&#xff0c;这个官网上还有其他类数据集&#xff0c;值得收藏&#xff01;&#xff01;&#xff01; 数据集介绍&#xff1a;宝安区-G4高速西乡大道入口车流量统计 第一行每列的标题…

什么是超导悬浮?工作原理是什么?

某些材料在冷却到某个温度&#xff08;也称为“临界温度”&#xff09;以下时会完全失去电阻。 1910 年&#xff0c;一位名叫 Heike Kamerlingh Onnes 的荷兰物理学家发现了这一现象。他注意到低于一定温度时电阻突然下降&#xff0c;然后他大胆地声称发现了一种新的物质状态&a…

字符串处理

读取 先定义&#xff1a; char ch[100];string s; cin>>s或cin>>ch以空格或换行符结束gets(ch);//gets只能读字符数组&#xff0c;不能直接读字符串stringgets和getline会把第一次出现的换行符及先前的字符串读进去&#xff08;包括空格&#xff09;&#xff0…

利用Flutter框架实现iOS应用的跨平台发布策略

本文探讨了使用Flutter开发的iOS应用能否上架&#xff0c;以及上架的具体流程。苹果提供了App Store作为正式上架渠道&#xff0c;同时也有TestFlight供开发者进行内测。合规并通过审核后&#xff0c;Flutter应用可以顺利上架。但上架过程可能存在一些挑战&#xff0c;因此可能…

【Linux】正则表达式实验操作实例

正则表达式是一种强大的工具&#xff0c;用于在文本中查找、匹配和替换特定的字符串模式。 实验目的 掌握正则表达式的表达方式掌握grep/egrep命令的用法掌握sed 命令的用法掌握awk命令的用法 正则表达式 实验目的实验内容实验过程创建grep文件来进行如下操作用sed命令完成下列…

HAL STM32 定时器PWM DMA输出方式

HAL STM32 定时器PWM DMA输出方式 &#x1f9e8;遗留问题&#xff1a;当配置RCR重复计数器&#xff0c;配置为2时&#xff0c;在定义了3组PWM参数情况下&#xff0c;只能输出第二组参数的PWM波形。&#xff08;HAL_TIM_PWM_Start_DMA(&htim1, TIM_CHANNEL_1, aCCValue_Buff…

Java中网络编程,Junit单元测试详解

文章目录 软件结构C/S结构B/S结构 概述三要素IP &#xff08;银行的位置&#xff09;端口 (银行中某个柜台号)协议 (填写取款单的规则)TCP通信程序TCP通信原理客户端发送数据服务端接收数据过程图三次握手 Junit单元测试概述常见的注解使用断言概述使用 软件结构 C/S结构 客户…

怀俄明探空站数据解算PWV和Tm

1. Matlab 获取代码可关注公众号WZZHHH回复&#xff08;怀俄明探空站数据解算PWV和Tm&#xff09;&#xff0c;或者咸鱼关注&#xff1a;WZZHHH123 怀俄明探空站数据解算PWV和Tm&#xff1a; 有关 Matlab 获取代码可关注公众号WZZHHH回复&#xff08;怀俄明多线程下载&#…

mysql_secure_installation初始化数据库报Access denied

使用mysql_secure_installation配置时出错&#xff1a; 可能输入密码错误&#xff0c;重新复制&#xff0c;粘贴密码。 或者&#xff1a; 登录mysql&#xff0c;设置密码&#xff0c;然后再设置权限。 mysql -u root -p [输入密码] sql>set passwordpassword("newPa…

数据同步工具datax安装配置与示例

文章目录 一、部署步骤1、jdk环境2、python环境步骤一&#xff1a;安装方式一&#xff1a;官网下载安装包方式二&#xff1a;brew命令安装 步骤二&#xff1a;配置环境变量步骤三&#xff1a;验证 3、maven环境&#xff08;可选&#xff09; 二、下载安装datax1、下载datax源码…

100 个网络基础知识,看完成半个网络高手

100 个网络基础知识&#xff0c;看完成半个网络高手。 1)什么是链接? 链接是指两个设备之间的连接。它包括用于一个设备能够与另一个设备通信的电缆类型和协议。 2)OSI 参考模型的层次是什么? 有 7 个 OSI 层&#xff1a;物理层&#xff0c;数据链路层&#xff0c;网络层&…

入门微调预训练Transformer模型

大家好&#xff0c;HuggingFace 为众多开源的自然语言处理&#xff08;NLP&#xff09;模型提供了强大的支持平台&#xff0c;让这些模型能够通过训练和微调来更好地服务于各种特定的应用场景。在大型语言模型&#xff08;LLM&#xff09;迅猛发展的今天&#xff0c;HuggingFac…

配置vscode用于STM32编译,Debug

配置环境参考&#xff1a; Docs 用cubemx配置工程文件&#xff0c;用VScode打开工程文件。 编译的时候会有如下报错&#xff1a; vscode出现process_begin :CreateProcess failed 系统找不到指定文件 解决方案&#xff1a;在你的makefile中加上SHELLcmd.exe就可以了 参考…

数据库系统

三级模式 外模式 数据库的用户使用的局部数据的逻辑结构和特征的描述数据库用户的数据视图&#xff0c;是与某一应用程序有关的数据的逻辑表示。 概念模式 它是数据库中全体数据的逻辑结构和特征的描述&#xff1b;模式是所有用户的公共数据视图。因为数据库是多人共享使用的&…

CICD流水线 发布公用jar到maven私仓

3.1 发布公用jar到Maven私仓 1.选择流水线 2.新建流水线 3.选择模版 4.选择代码仓库 5. 调整构建命令 6.新增一个新阶段为 ”发送通知“&#xff0c;这里以邮件通知为例&#xff0c;保存之后&#xff0c;运行该流水线&#xff0c;对应jar就会自动发到我们私仓&#xff0c;并之…

春招-实战项目冲刺直播课

春招-实战项目冲刺直播课 CCtalk 丰富多元的综合内容平台-专业的知识分享与在线教育平台https://www.cctalk.com/m/group/91161801

CTF之社工-初步收集

题目就一个刷钻网站&#xff08;假的&#xff09; 扫描一下目录 发现还有一个登录界面 时间多的可以爆破一下&#xff08;反正我爆不出来&#xff09;&#xff0c;接着我们下载那个压缩包看看 发现是一个钓鱼小软件 没发现什么有用的信息那我们就去wireshark看看数据包喽&#…

winform 等待加载窗体

winform 等待加载窗体 当我们查询sql语句或处理大量的数据时&#xff0c;为了防止界面假死状态&#xff0c;可以加一个等待窗体过渡一下。 1. 新建一个主窗体&#xff0c;一个等待窗体frmLoading 2. 给等待窗体增加一个动态图片 3. 在主窗体中调用 namespace winformLoading…

解析以及探讨数据库技术及其应用

一&#xff0c;引言 数据库作为信息时代的基石&#xff0c;是一种用于高效存储、管理和检索大量结构化数据的系统。它的核心价值在于提供了一种可靠且可扩展的方式&#xff0c;将复杂多样的数据按照特定结构和规则组织起来&#xff0c;以便于不同用户和应用程序进行访问和使用。…

揭秘!接口自动化测试应该做什么?

在软件开发过程中&#xff0c;接口测试是一个至关重要的环节&#xff0c;它确保了系统或组件之间的数据交换、传递和控制管理过程以及相互逻辑依赖关系的正确性。传统的瀑布软件流程中&#xff0c;测试人员在做某个系统的手工功能测试时&#xff0c;会首先从业务人员或开发人员…