c语言实现—动态通讯录

news2024/12/27 17:13:33

一.前言

      上次带大家认识了一下顺序表,其实我们可以在顺序表的基础上实现一个通讯录的小项目,通讯录的本质仍然是顺序表,所以如果下面的代码你有问题的话,先去看看我的上篇文章哦~。

 

 

通讯录的功能大家应该都知道吧,这次我们就要用C语言实现一个通讯录的基本功能:

  • 储存人的信息

其中每个人的信息包括:
名字 性别 年龄 地址 电话号码

  • 增加人的信息
  • 删除指定人的信息
  • 修改指定人的信息
  • 查找指定人的信息
  • 查看通讯录的信息

二.功能实现

1.通讯录信息格式的初始化 

#pragma once
//#include<stdio.h>
//#include"SeqList.h"
#define NAME_MAX 100
#define GENDER_MAX 12
#define TEL_MAX 12
#define ADDR_MAX 100
//通讯录数据类型
typedef struct PersonInfo
{
	char name[NAME_MAX];
	int age;
	char gender[GENDER_MAX];
	char tel[TEL_MAX];
	char addr[ADDR_MAX];
}Info;

struct SeqList;
typedef struct SeqList Contact;
//通讯录提供的操作

//通讯录的初始化和销毁
void ContactInit(Contact*pcon);
void ContactDestory(Contact* pcon);

//增删修查
void ContactAdd(Contact* pcon);
void ContactDel(Contact* pcon);
void ContactModify(Contact* pcon);
void ContactFind(Contact* pcon);
void ContactShow(Contact* pcon);

2.通讯录初始化

void ContactInit(Contact* pcon)
{
	SLInit(pcon);
}
//SLInit(pcon)函数的伪代码如下
void SLInit(SL* ps) {
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}

3.添加联系人

void ContactAdd(Contact* pcon)
{
	Info info;
	printf("请输入联系人姓名:\n");
	scanf("%s", info.name);
	printf("请输入联系人年龄:\n");
	scanf("%d", &info.age);
	printf("请输入联系人性别:\n");
	scanf("%s", info.gender);
	printf("请输入联系人电话:\n");
	scanf("%s", info.tel);
	printf("请输入联系人地址:\n");
	scanf("%s", info.addr);
	//保存数据到通讯录里(通讯录)
	SLPushBack(pcon,info);
}

4.删除联系人

void ContactDel(Contact* pcon)
{
	//删除之前先查找
	printf("请输入联系人姓名:\n");
	char name[NAME_MAX];
	scanf("%s", name);
	int findIndex = FindByName(pcon,name);
	if (findIndex <0)
	{
		printf("要删除的联系人不存在\n");
		return;
	}
	SLErase(pcon, findIndex);
	printf("联系人删除成功\n");
	
}
//FindByName(pcon,name)函数的伪代码如下
int  FindByName(Contact*pcon,char name[])
{
	
	for (int i=0;i<pcon->size;i++)
	{
		if (strcmp(pcon->arr[i].name, name) == 0)
		{
			return i;
		}
		
	}
	return -1;
}

5.修改联系人信息

void ContactModify(Contact* pcon)
{
	printf("请输入联系人姓名:\n");
	char name[NAME_MAX];
	scanf("%s", name);
	int findIndex = FindByName(pcon, name);
		if (findIndex < 0)
		{
			printf("要修改的联系人不存在\n");
			return;
		}
    //找到了
		printf("请输入联系人姓名:\n");
		scanf("%s", pcon->arr[findIndex].name);
		printf("请输入联系人年龄:\n");
		scanf("%d", &pcon->arr[findIndex].age);
		printf("请输入联系人性别:\n");
		scanf("%s", pcon->arr[findIndex].gender);
		printf("请输入联系人电话:\n");
		scanf("%s", pcon->arr[findIndex].tel);
		printf("请输入联系人地址:\n");
		scanf("%s", pcon->arr[findIndex].addr);
		printf("联系人修改成功\n");

}

6.查找联系人信息

void ContactFind(Contact*pcon)
{
	char name[NAME_MAX];
	printf("请输入要查找的联系人的姓名\n");
	scanf("%s",name);
	int findIndex = FindByName(pcon, name);
	if (findIndex < 0)
	{
		printf("要查找的联系人不存在\n");
		return;
	}
	printf("%s %s %s %s %s\n","姓名","年龄","性别","电话","住址");
	printf("%s %d %s %s %s\n",
		pcon->arr[findIndex].name,
		pcon->arr[findIndex].age,
		pcon->arr[findIndex].gender,
		pcon->arr[findIndex].tel,
		pcon->arr[findIndex].addr
	);

}

 7.打印通讯录信息

void ContactShow(Contact* pcon)
{
	printf("%s %s %s %s %s\n", "姓名", "年龄", "性别", "电话", "住址");
	for (int i = 0; i < pcon->size; i++)
	{
		printf("%s %d %s %s %s\n",
			pcon->arr[i].name,
			pcon->arr[i].age,
			pcon->arr[i].gender,
			pcon->arr[i].tel,
			pcon->arr[i].addr
		    );
	}
}

三.SeqList.h

#define _CRT_SECURE_NO_WARNINGS 1
#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include"Contact.h"


//静态顺序表

//#define N 100
//struct SeqList
//{
//	SLDataType a[N];
//	int size;
//};

//动态顺序表

//typedef int SLDataType;
typedef Info SLDataType;

typedef struct SeqList
{
	SLDataType* arr; //存储数据的底层结构
	int capacity;    //记录顺序表的空间大小
	int size;        //记录顺序表当前有效的数据个数
}SL;

//typedef struct SeqList SL;

//初始化和销毁
void SLInit(SL* ps);
void SLDestroy(SL* ps);
void SLPrint(SL* ps); //保持接口一致性

//顺序表的头部/尾部插入
void SLPushBack(SL* ps, SLDataType x);
void SLPushFront(SL* ps, SLDataType x);

//顺序表的头部/尾部删除
void SLPopBack(SL* ps);
void SLPopFront(SL* ps);

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

四.SeqList.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"SeqList.h"
//初始化和销毁
void SLInit(SL* ps) {
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}

void SLCheckCapacity(SL* ps) {
	if (ps->size == ps->capacity) {
		int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
		SLDataType* tmp = (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 != NULL);
	assert(ps);

	//if判断--温柔的解决方式
	//if (ps == NULL) {
	//	return;
	//}

	//空间不够,扩容
	SLCheckCapacity(ps);

	//空间足够,直接插入
	ps->arr[ps->size++] = x;
	//ps->size++;
}
void SLPushFront(SL* ps, SLDataType x) {
	assert(ps);

	//判断是否扩容
	SLCheckCapacity(ps);

	//旧数据往后挪动一位
	for (int i = ps->size; i > 0; i--) //i = 1
	{
		ps->arr[i] = ps->arr[i - 1]; //ps->arr[1] = ps->arr[0]
	}
	ps->arr[0] = x;
	ps->size++;
}

//顺序表的头部/尾部删除
void SLPopBack(SL* ps) {
	assert(ps);
	assert(ps->size);

	//顺序表不为空
	//ps->arr[ps->size - 1] = -1;
	ps->size--;
}
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 SLInsert(SL* ps, int pos, SLDataType x) {
	assert(ps);
	assert(pos >= 0 && pos <= ps->size);

	SLCheckCapacity(ps);

	//pos及之后的数据往后挪动一位,pos空出来
	for (int i = ps->size; i > pos; i--)
	{
		ps->arr[i] = ps->arr[i - 1]; //ps->arr[pos+1] = ps->arr[pos]
	}
	ps->arr[pos] = x;
	ps->size++;
}
//删除指定位置数据
void SLErase(SL* ps, int pos) {
	assert(ps);
	assert(pos >= 0 && pos < ps->size);

	//pos以后的数据往前挪动一位
	for (int i = pos; i < ps->size - 1; i++)
	{
		ps->arr[i] = ps->arr[i + 1];//ps->arr[i-2] = ps->arr[i-1];
	}
	ps->size--;
}
//查找x
//int SLFind(SL* ps, SLDataType x)
//{
//	assert(ps);
//	for (int i = 0; i < ps->size; i++)
//	{
//		if (ps->arr[i] == x)
//			return i;
//	}
//	return -1;
//}
void SLDestroy(SL* ps) {
	    assert(ps);
		if (ps->arr)
		{
			free(ps->arr);
		}
		ps->arr = NULL;
		ps->size = ps->capacity = 0;
}

void SLPrint(SL* ps) {
	for (int i = 0; i < ps->size; i++)
	{
		printf("%d ", ps->arr[i]);
	}
	printf("\n");
}

五.Contact.h

#pragma once
//#include<stdio.h>
//#include"SeqList.h"
#define NAME_MAX 100
#define GENDER_MAX 12
#define TEL_MAX 12
#define ADDR_MAX 100
//通讯录数据类型
typedef struct PersonInfo
{
	char name[NAME_MAX];
	int age;
	char gender[GENDER_MAX];
	char tel[TEL_MAX];
	char addr[ADDR_MAX];
}Info;

struct SeqList;
typedef struct SeqList Contact;
//通讯录提供的操作

//通讯录的初始化和销毁
void ContactInit(Contact*pcon);
void ContactDestory(Contact* pcon);

//增删修查
void ContactAdd(Contact* pcon);
void ContactDel(Contact* pcon);
void ContactModify(Contact* pcon);
void ContactFind(Contact* pcon);
void ContactShow(Contact* pcon);

六.Contact.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"Contact.h"
#include"SeqList.h"
//通讯录的初始化和销毁
void ContactInit(Contact* pcon)
{
	SLInit(pcon);
}
void ContactDestory(Contact* pcon)
{
	SLDestroy(pcon);
}

//增删修查
void ContactAdd(Contact* pcon)
{
	Info info;
	printf("请输入联系人姓名:\n");
	scanf("%s", info.name);
	printf("请输入联系人年龄:\n");
	scanf("%d", &info.age);
	printf("请输入联系人性别:\n");
	scanf("%s", info.gender);
	printf("请输入联系人电话:\n");
	scanf("%s", info.tel);
	printf("请输入联系人地址:\n");
	scanf("%s", info.addr);
	//保存数据到通讯录里(通讯录)
	SLPushBack(pcon,info);
}
int  FindByName(Contact*pcon,char name[])
{
	
	for (int i=0;i<pcon->size;i++)
	{
		if (strcmp(pcon->arr[i].name, name) == 0)
		{
			return i;
		}
		
	}
	return -1;
}
//void ContactFind(Contact* pcon)
//{
//
//}
void ContactDel(Contact* pcon)
{
	//删除之前先查找
	printf("请输入联系人姓名:\n");
	char name[NAME_MAX];
	scanf("%s", name);
	int findIndex = FindByName(pcon,name);
	if (findIndex <0)
	{
		printf("要删除的联系人不存在\n");
		return;
	}
	SLErase(pcon, findIndex);
	printf("联系人删除成功\n");
	
}
void ContactModify(Contact* pcon)
{
	printf("请输入联系人姓名:\n");
	char name[NAME_MAX];
	scanf("%s", name);
	int findIndex = FindByName(pcon, name);
		if (findIndex < 0)
		{
			printf("要修改的联系人不存在\n");
			return;
		}
    //找到了
		printf("请输入联系人姓名:\n");
		scanf("%s", pcon->arr[findIndex].name);
		printf("请输入联系人年龄:\n");
		scanf("%d", &pcon->arr[findIndex].age);
		printf("请输入联系人性别:\n");
		scanf("%s", pcon->arr[findIndex].gender);
		printf("请输入联系人电话:\n");
		scanf("%s", pcon->arr[findIndex].tel);
		printf("请输入联系人地址:\n");
		scanf("%s", pcon->arr[findIndex].addr);
		printf("联系人修改成功\n");

}

void ContactShow(Contact* pcon)
{
	printf("%s %s %s %s %s\n", "姓名", "年龄", "性别", "电话", "住址");
	for (int i = 0; i < pcon->size; i++)
	{
		printf("%s %d %s %s %s\n",
			pcon->arr[i].name,
			pcon->arr[i].age,
			pcon->arr[i].gender,
			pcon->arr[i].tel,
			pcon->arr[i].addr
		    );
	}
}
void ContactFind(Contact*pcon)
{
	char name[NAME_MAX];
	printf("请输入要查找的联系人的姓名\n");
	scanf("%s",name);
	int findIndex = FindByName(pcon, name);
	if (findIndex < 0)
	{
		printf("要查找的联系人不存在\n");
		return;
	}
	printf("%s %s %s %s %s\n","姓名","年龄","性别","电话","住址");
	printf("%s %d %s %s %s\n",
		pcon->arr[findIndex].name,
		pcon->arr[findIndex].age,
		pcon->arr[findIndex].gender,
		pcon->arr[findIndex].tel,
		pcon->arr[findIndex].addr
	);

}

七.Contest.c

#define _CRT_SECURE_NO_WARNINGS 1
//#include"Contact.h"
#include"SeqList.h"
void menu()
{
	printf("*****************通讯录***************\n");
	printf("*******1.添加联系人  2.删除联系人*****\n");//ctrl+d
	printf("*******3.修改联系人  4.查找联系人*****\n");//ctrl+d
	printf("*******5.查看通讯录  0.  退 出  ******\n");//ctrl+d
	printf("**************************************\n");
}
int main()
{
	int op = 0;
	//创建通讯录结构
	Contact con;
	ContactInit(&con);
	do
	{
		menu();
		printf("请输入需要的操作\n");
		scanf("%d",&op);
		switch (op)
		{
		case 1:
			ContactAdd(&con);
			break;
		case 2:
			ContactDel(&con);
			break;
		case 3:
			ContactModify(&con);
			break;
		case 4:
			ContactFind(&con);
			break;
		case 5:
			ContactShow(&con);
			break;
		case 0:
			printf("通讯录退出中\n");
			break;
		default:
			break;
		}

	} while (op);
	//销毁通讯录
	ContactDestory(&con);
	return 0;
}

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

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

相关文章

记 Rxjava zip操作符遇到的问题

在项目中遇到了类似下面这样的代码 本意是希望当zip操作符中三个Observable执行完毕之后&#xff0c;将他们返回的数据统一进行处理 Observable.zip(startFirst(), startSecond(), startThird(),(first, second, third) -> {Log.i("Rxjava", "handle all dat…

鸿蒙开发(八)添加常用控件(下)

添加控件的文章分成了上下两篇&#xff0c;上篇介绍了文本显示、文本输入、按钮、图片、单选框、切换按钮这六种常用控件&#xff0c;本篇继续介绍其他几种很重要但略微复杂的控件。 鸿蒙系列上一篇&#xff1a; 鸿蒙开发&#xff08;七&#xff09;添加常用控件&#xff08;…

网络安全防御保护实验(二)

一、登录进防火墙的web控制页面进行配置安全策略 登录到Web控制页面&#xff1a; 打开Web浏览器&#xff0c;输入防火墙的IP地址或主机名&#xff0c;然后使用正确的用户名和密码登录到防火墙的Web管理界面。通常&#xff0c;这些信息在防火墙设备的文档或设备上会有说明。 导…

[晓理紫]每日论文分享(有中文摘要,源码或项目地址)-机器人、强化学习

专属领域论文订阅 关注{晓理紫}&#xff0c;每日更新论文&#xff0c;如感兴趣&#xff0c;请转发给有需要的同学&#xff0c;谢谢支持 如果你感觉对你有所帮助&#xff0c;请关注我&#xff0c;每日准时为你推送最新论文。 分类: 具身智能&#xff0c;机器人强化学习开放词汇&…

[C++开发 03_2/2 _ STL(185)]

知识点1&#xff1a;STL初始 概述&#xff1a; STL是标准模板库的意思&#xff0c;STL从广义上来讲分为&#xff1a;容器&#xff0c;算法&#xff0c;迭代器。 容器算法之间通过迭代器进行无缝连接。 知识点2&#xff1a;STL初始 2.1 STL诞生 C中面向对象的三大特性&#xff1…

九、Kotlin 注解

1. 什么是注解 注解是对程序的附件信息说明。 注解可以作用在类、函数、函数参数、属性等上面。 注解的信息可用于源码级、编译期、运行时。 2. 注解类的定义 使用元注解 Retention 声明注解类的作用时期。 使用元注解 Target 声明注解类的作用对象。 定义注解类时可以声…

8.6 代理设计模式

文章目录 一、代理模式&#xff08;Proxy Pattern&#xff09;概述二、代理模式和观察者设计模式三、模式结构四、协作角色五、实现策略六、相关模式七、示例八、应用 一、代理模式&#xff08;Proxy Pattern&#xff09;概述 代理模式是一种设计模式&#xff0c;它通过引入一个…

Windows Defender存在威胁执行操作无反应且一直存在红叉(已解决)

文章目录 前言问题如图一、原因二、解决办法&#xff08;亲试有效&#xff09;总结 前言 Windows安全中心&#xff08;Windows Defender&#xff09;执行快速扫描/完全扫描后一直存在威胁&#xff0c;执行隔离或者删除操作后下次扫描还会扫出该威胁&#xff0c;但看威胁文件位置…

38、Flink 的CDC 格式:canal部署以及示例

Flink 系列文章 一、Flink 专栏 Flink 专栏系统介绍某一知识点&#xff0c;并辅以具体的示例进行说明。 1、Flink 部署系列 本部分介绍Flink的部署、配置相关基础内容。 2、Flink基础系列 本部分介绍Flink 的基础部分&#xff0c;比如术语、架构、编程模型、编程指南、基本的…

leetcode1237. 找出给定方程的正整数解

1237. 找出给定方程的正整数解https://leetcode.cn/problems/find-positive-integer-solution-for-a-given-equation/ 难度中等 101 给你一个函数 f(x, y) 和一个目标结果 z&#xff0c;函数公式未知&#xff0c;请你计算方程 f(x,y) z 所有可能的正整数 数对 x 和 y。满…

java生成验证码工具类,java生成图片验证码

java生成验证码工具类&#xff0c;java生成图片验证码 java生成验证码工具类&#xff0c;java生成图片验证码&#xff0c;java生成彩色图片验证码&#xff0c;带干扰线验证码。 调用结果&#xff1a; 工具类调用&#xff1a; GetMapping("/validateCode")public vo…

ubuntu设置右键打开terminator、code

前言&#xff1a; 这里介绍一种直接右键打开本地目录下的terminator和vscode的方法。 一&#xff1a;右键打开terminator 1.安装terminator sudo apt install terminator 2.安装nautilus-actions filemanager-actions sudo apt-get install nautilus-actions filemanager…

【大数据】Flink 中的事件时间处理

Flink 中的事件时间处理 1.时间戳2.水位线3.水位线传播和事件时间4.时间戳分配和水位线生成 在之前的博客中&#xff0c;我们强调了时间语义对于流处理应用的重要性并解释了 处理时间 和 事件时间 的差异。虽然处理时间是基于处理机器的本地时间&#xff0c;相对容易理解&#…

可视化智慧水电站EasyCVR视频智能监控系统方案设计与技术应用介绍

一、背景需求 水电站作为国家重要的能源基地&#xff0c;其安全运行对于保障能源供应和社会稳定具有重要意义。然而&#xff0c;传统的人工监控方式存在着诸多问题&#xff0c;如人力成本高、监控范围有限、反应不及时等。因此&#xff0c;水电站急需引进一种先进的视频智能监…

《Q年文峰》GPT应用的交互式非线性体验

Phoncent博客创始人庄泽峰把自己的小说《Q年文峰》做成GPT应用&#xff0c;显然这是一件值得探索且具有创新意义的事情。 因为传统的阅读体验是线性的&#xff0c;读者只能按照固定的情节顺序进行阅读&#xff0c;而把小说制作成GPT应用后&#xff0c;读者阅读小说的方式是非线…

安卓程序开发——搭建主页框架

一、实验目的 搭建项目框架掌握Android Activity组件使用和Intent机制&#xff0c;加强对Activity生命周期的理解&#xff0c;掌握Fragment的使用。 二、实验设备及器件 Android Studio 三、实验内容 1.创建一个Android应用&#xff0c;设置工程名MobileShop&#xff0c;包…

鸿蒙ArkUI开发-应用添加弹窗

在我们日常使用应用的时候&#xff0c;可能会进行一些敏感的操作&#xff0c;比如删除联系人&#xff0c;这时候我们给应用添加弹窗来提示用户是否需要执行该操作&#xff0c;如下图所示&#xff1a; 弹窗是一种模态窗口&#xff0c;通常用来展示用户当前需要的或用户必须关注的…

智能体AI Agent的极速入门:从ReAct到AutoGPT、QwenAgent、XAgent

前言 如这两天在微博上所说&#xff0c;除了已经在七月官网上线的AIGC模特生成系统外&#xff0c;我正在并行带多个项目组 第二项目组&#xff0c;论文审稿GPT第2版的效果已经超过了GPT4&#xff0c;详见《七月论文审稿GPT第2版&#xff1a;用一万多条paper-review数据集微调…

PBM模型学习(二)Discrete离散方法

1.Discreate离散方法主要涉及Bins的分区、粒径设置、颗粒粒径、Phenomena,如下图所示: ## 2.重要参数设置 Bins分区 Bins表示将颗粒分成了几份 也就是说在PBM模型中,颗粒粒径是离散的,比如实际的颗粒粒径可能是0.001m-0.01m范围内,那么颗粒在这个范围内粒径应该是比较连续…

幻兽帕鲁游戏服务器搭建by阿里云服务器4核16G和32G配置价格表

如何自建幻兽帕鲁服务器&#xff1f;基于阿里云服务器搭建幻兽帕鲁palworld服务器教程来了&#xff0c;一看就懂系列。本文是利用OOS中幻兽帕鲁扩展程序来一键部署幻兽帕鲁服务器&#xff0c;阿里云百科aliyunbaike.com分享官方基于阿里云服务器快速创建幻兽帕鲁服务器教程&…