通讯录项目(终)

Start And Stick

上一期我们将通讯录的项目的基本功能已经实现,这一篇文章我们将对通讯录进行完善。

目录

Start And Stick

上期回顾:

上期必要代码:

数据打印:

代码讲解:

头部插入数据:

代码讲解:

任意位置数据修改:

代码讲解:

最代码整合:

sqlist.h文件:

slist.c文件:

test.c文件:


上期回顾:

通讯录(上)icon-default.png?t=N7T8http://t.csdnimg.cn/Vg3o3

话不多说我们开始代码实现:

上期必要代码:

typedef struct pereon
{
	char name[20];
	int age;
	char gender[2];
	char phone[13];
}PE;

typedef PE WANG;

typedef struct sqlist {
	WANG* a;
	int cp;
	int numbers;
}SL;

数据打印:

//数据打印
void SLprint(SL* p1) {
	assert(p1);
	printf("%s %s %s %s\n", "姓名", "年龄", "性别", "电话");
	for (int i = 0; i < p1->numbers; i++)
	{
		printf("%-s %-d %-s %-s\n",
			p1->a[i].name,
			p1->a[i].age,
			p1->a[i].gender,
			p1->a[i].phone
		);
	}
}

代码讲解:

这里打印字符串需要用%s,打印整形需要用%d。这里我们需要着重讲解的是:

p1->a[i]表示的意思。首先根据运算先后顺序p1->a先结合,结合后可以看作:WANG*a。之后可以看作a[i],也就是*(a+i)。这里*(a+i)又可以看作PE,对其进行引用可以。

数据销毁:

//数据销毁
void SLdestory(SL* p1) {
	assert(p1);
	free(p1->a);
	p1->a = NULL;
	p1->cp = p1->numbers = 0;

}

对结点进行释放内存,同时对数据进行初始化。

头部插入数据:

这里会有读者问为啥头部插入数据要放在这一篇文章讲呢,肯定是有一点特殊啊!!

//数据头部插入
void SLheaddeposit(SL*p1)
{
	int mz = p1->cp == 0 ? 2 : 2 * p1->cp;
	if (p1->cp == p1->numbers) {
		p1->a = (WANG*)realloc(p1->a, mz * sizeof(WANG));
		p1->cp = mz;
	}
	assert(p1);
	WANG p2 = inform();
	//将原本的数据移动
	for (int i = p1->numbers; i>=0 ; i--)
	{
		if (i == 0)
		{
			p1->a[i] = p2;
		}
		p1->a[i] = p1->a[i - 1];
	}
}

代码讲解:

我们这里还是要判断是否要申请空间,也就和前面一样。接下来我们需要将录入的新数据先存入我们所定义的零时变量p2中,之后我们需要将原本的数据从后开始移动,以防止数据的覆盖问题。

任意位置数据修改:

最后我们来实现任意指定位置的数据删除和插入,因为两者的思路差不多所以我们仅实现一个:

这里我们来实现任意位置的数据插入:

void SLanydeposit(SL*p1)
{
	assert(p1);
	int m = 0;
	printf("请输入想要插入数据的下标:");
	scanf("%d", &m);
	//录入数据,
	PE p = inform();
	//将原本的数据移动,插入数据
		for (int i = p1->numbers; i >= m; i--)
		{

			if (i == m)
			{
				p1->a[i] = p;
			}
			else
			{
				p1->a[i] = p1->a[i - 1];
			}
			
		}
}

代码讲解:

这里我们需要考虑一个事情:如果i=p1->numbers=0,这里我们的m只能为0。所以for循环也可以处理该数据的插入。

这里代码的目录和选择可以根据自己的喜好来进行更改。

最代码整合:

最后我们进行代码的整合,test.c文件和sqlist.h我们就不再讲解了。

sqlist.h文件:

#pragma once

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<string.h>

typedef struct pereon
{
	char name[20];
	int age;
	char gender[2];
	char phone[13];
}PE;

typedef PE WANG;

typedef struct sqlist {
	WANG* a;
	int cp;
	int numbers;
}SL;

//数据存放

PE inform();

//数据尾部插入
void SLdeposit(SL* p1);

//数据删除
void SLdelete(SL* p1);

//数据查找
int SLfind(SL* p1);

//数据打印
void SLprint(SL* p1);

//数据销毁
void SLdestory(SL* p1);

//图表打印
void menu();

//数据初始化
void SLinit(SL* p1);

//数据头部插入
void SLheaddeposit(SL* p1);

//任意位置数据前的插入
void SLanydeposit(SL* p1);

slist.c文件:

#define _CRT_SECURE_NO_WARNINGS 1
#include"sqlist.h"


//数据初始化
void SLinit(SL* p1)
{
	p1->a = NULL;
	p1->cp = p1->numbers = 0;
}

//数据录入
PE inform()
{
	printf("请输入数据:");
	PE inof;
	printf("请输入name:");
	scanf("%s", inof.name);
	printf("请输入age:");
	scanf("%d", &inof.age);
	printf("请输入gender:");
	scanf("%s", inof.gender);
	printf("请输入phone number:");
	scanf("%s", inof.phone);
	return inof;
}

//数据头部插入
void SLheaddeposit(SL*p1)
{
	int mz = p1->cp == 0 ? 2 : 2 * p1->cp;
	if (p1->cp == p1->numbers) {
		p1->a = (WANG*)realloc(p1->a, mz * sizeof(WANG));
		p1->cp = mz;
	}
	assert(p1);
	WANG p2 = inform();
	//将原本的数据移动
	for (int i = p1->numbers; i>=0 ; i--)
	{
		if (i == 0)
		{
			p1->a[i] = p2;
		}
		p1->a[i] = p1->a[i - 1];
	}
}



//数据尾部插入
void SLdeposit(SL* p1)
{
	int mz = p1->cp == 0 ? 2 : 2 * p1->cp;
	if (p1->cp == p1->numbers) {
		p1->a = (WANG*)realloc(p1->a, mz * sizeof(WANG));
		p1->cp = mz;
	}
	assert(p1);
	p1->a[p1->numbers] = inform();
	p1->numbers++;
}

//数据删除
void SLdelete(SL* p1)
{
	assert(p1);
	int i = SLfind(p1);
	if(i>=0);
	{
		for (int m = i; m < p1->numbers-1; m++)
		{
			p1->a[m] = p1->a[m + 1];
		}
		printf("删除成功\n");
		p1->numbers--;
	}
	if (i == -1) {
		printf("no people is this name\n");
	}
}

//数据查找
int SLfind(SL*p1)
{
	assert(p1);
	printf("please write your name:");
	char name[20];
	scanf("%s", name);
	for (int i = 0; i < p1->numbers; i++)
	{
		int m=strcmp(name, p1->a[i].name);
		if (m == 0)
		printf("%s %s %s %s\n", "姓名", "年龄", "性别", "电话");
		printf("%-s %-d %-s %-s\n",
			p1->a[i].name,
			p1->a[i].age,
			p1->a[i].gender,
			p1->a[i].phone
		);
			return i;
	}
	printf("查找失败\n");
	return -1;
}

//数据打印
void SLprint(SL* p1) {
	assert(p1);
	printf("%s %s %s %s\n", "姓名", "年龄", "性别", "电话");
	for (int i = 0; i < p1->numbers; i++)
	{
		printf("%-s %-d %-s %-s\n",
			p1->a[i].name,
			p1->a[i].age,
			p1->a[i].gender,
			p1->a[i].phone
		);
	}
}

//数据销毁
void SLdestory(SL* p1) {
	assert(p1);
	free(p1->a);
	p1->a = NULL;
	p1->cp = p1->numbers = 0;

}

//图表打印
void menu()
{
	printf("**************\n");
	printf("****通讯录****\n");
	printf("*1.增加联系人*\n");
	printf("*2.删除联系人*\n");
	printf("*3.查找联系人*\n");
	printf("*4.显示联系人*\n");
	printf("**0.退出服务**\n");
	printf("**************\n");
	printf("**************\n");
}
//任意位置数据前的插入
void SLanydeposit(SL*p1)
{
	assert(p1);
	int m = 0;
	printf("请输入想要插入数据的下标:");
	scanf("%d", &m);
	//录入数据,
	PE p = inform();
	//将原本的数据移动,插入数据
		for (int i = p1->numbers; i >= m; i--)
		{

			if (i == m)
			{
				p1->a[i] = p;
			}
			else
			{
				p1->a[i] = p1->a[i - 1];
			}
			
		}
}

test.c文件:


#include"sqlist.h"


int main()
{
	int choice = 0;
	SL connect;
	SL* p1 = &connect;
	SLinit(p1);
	do
	{
		menu();
		printf("Please make your owen choice: ");
		scanf("%d", &choice);
		switch (choice)
		{
		case 1:
		SLdeposit(p1);
			break;
		case 2:
			SLdelete(p1);
			break;
		case 3:
			SLfind(p1);
			break;
		case 4:
			SLprint(p1);
			break;
		case 0:
			printf("退出成功");
			break;
		default:
			printf("输入错误");
			break;
		}

	} while (choice);


	return 0;
}

到这里我们的结构体实现通讯录就结束了,我们江湖再见。

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

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

相关文章

27.1K Star,优雅的JSON 数据可视化工具

Hi&#xff0c;骚年&#xff0c;我是大 G&#xff0c;公众号「GitHub指北」会推荐 GitHub 上有趣有用的项目&#xff0c;一分钟 get 一个优秀的开源项目&#xff0c;挖掘开源的价值&#xff0c;欢迎关注。 想自己之前做 APP 开发会访问后端数据&#xff0c;这个数据就是 JSON …

【网络基础】网络协议传输层UDP和TCP

UDP 解包和分用 解包&#xff08;解析数据包&#xff09; 捕获数据包&#xff1a;首先&#xff0c;接收端的网络栈捕获UDP数据包。检查目的端口&#xff1a;接收端检查数据包头部的目的端口&#xff0c;以确定哪个应用程序应该接收该数据包。验证校验和&#xff1a;接收端可能…

【排序5】基数排序:数字的组织与整理艺术

&#x1f3a1;基数排序 &#x1f38a;1、基本思想&#x1f38a;2、基本步骤&#x1f38a;3、代码示例&#x1f38a;4、特性总结 &#x1f38a;1、基本思想 基数排序&#xff08;Radix Sort&#xff09;是一种非比较排序算法&#xff0c;它根据数字的每一位来对元素进行排序。它…

2024年数学建模美赛C题(预测 Wordle)——思路、程序总结分享

1: 问题描述与要求 《纽约时报》要求您对本文件中的结果进行分析&#xff0c;以回答几个问题。 问题1&#xff1a;报告结果的数量每天都在变化。开发一个模型来解释这种变化&#xff0c;并使用您的模型为2023年3月1日报告的结果数量创建一个预测区间。这个词的任何属性是否会…

Java TemporalAdjusters 时间调节器

提供了非常多处理日期相关的函数&#xff1a; 使用示例&#xff1a; /*** JCccc* param args*/public static void main(String[] args) {DateTimeFormatter pattern DateTimeFormatter.ofPattern("yyyy-MM-dd");LocalDateTime now LocalDateTime.now();//获取当月…

web前端项目-实现录音功能【附源码】

录音功能 运行效果&#xff1a;本项目可实现录音软件的录音、存储、播放等功能 HTML源码&#xff1a; &#xff08;1&#xff09;index.html&#xff1a; <!DOCTYPE html> <html><head><meta http-equiv"Content-Type" content"text/h…

java日志框架总结(三 、Log4j日志框架)

一、简介 Log4j ( Logger For Java ) , Java 日志的记录包。 官方网站 。Log4j 是 Apache 的一个开源项目&#xff0c; 为Java提供了日志记录功能。能够让程序员非常方便的记录日志&#xff0c; 并且提供了多种适配方式&#xff0c;能满足各种需求。 使用Log4j 只需要导入一个…

【时序预测】2、prophet:Forecasting at Scale | Python 文档教程

文章目录 一、Quick Start二、饱和预测2.1 Forecasting Growth 预测增长2.2 Saturating Minimum 饱和最小值 三、Trend Changepoints 趋势变化点3.1 Automatic changepoint detection in Prophet 自动检测变化点3.2 Adjusting trend flexibility 调整趋势灵活性3.3 Specifying …

从零开始做题:逆向 ret2shellcode orw

1.题目信息 BUUCTF在线评测 下载orw时防病毒要关闭 2.题目分析 orw是open、read、write的简写。有时候binary会通过prctl、seccomp进行沙箱保护&#xff0c;并不能getshell。只能通过orw的方式拿到flag。 fdopen&#xff08;‘./flag’); # 打开flag文件&#xff0c;得到fd…

线程调度(Java Android)

关于作者&#xff1a;CSDN内容合伙人、技术专家&#xff0c; 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 &#xff0c;擅长java后端、移动开发、商业变现、人工智能等&#xff0c;希望大家多多支持。 未经允许不得转载 目录 一、导读二、概览2.1、线程的属性 三、…

HTTP服务器基础认识(复习)

鉴于曾经写过相关文章&#xff0c;这里就不再详细介绍了&#xff0c;关于详细的介绍可以参考我之前的文章 HTTP协议初识中篇-CSDN博客 一个简单的设置套接字的过程&#xff0c;也当成是复习一下下了 代码 #include <iostream> #include <cstdio> #include <…

Redis的数据类型

目录 string 1.编码方式 2.应用场景 3.常用命令 hash 1.编码方式 2.应用场景 3.常用命令 list 1.编码方式 2.应用场景 3.常用命令 set 1.编码方式 2.应用场景 3.常用命令 zset 1.编码方式 2.应用场景 3.常用命令 如何理解Redis的编码方式 embs…

2024三掌柜赠书活动第七期:一本书读懂AIGC:探索AI商业化新时代

目录 前言AI商业化的背景和挑战关于《一本书读懂AIGC&#xff1a;探索AI商业化新时代》编辑推荐内容简介作者简介图书目录书中前言/序言《一本书读懂AIGC&#xff1a;探索AI商业化新时代》全书速览结束语 前言 不用多讲&#xff0c;想必大家也都知道&#xff0c;人工智能在过…

k8s-基础知识(Service,NodePort,CusterIP,无头服务,NameSpace,资源限制)

Node Node 是 Pod 真正运行的主机&#xff0c;可以是物理机&#xff0c;也可以是虚拟机。 Annotations 原文链接 Annotations 是 key/value 形式附加于对象的注解。不同于 Labels 用于标志和选择对象&#xff0c;Annotations 则是用来记录一些附加信息&#xff0c;用来辅助应…

【标定】多源LiDAR传感器标定方法(含C++代码)

提供的代码是一种使用平面提取和匹配以及随后的Ceres Solver库优化转换的LiDAR标定方法的全面实现。这种方法用于对齐多个LiDAR传感器的数据,比如那些安装在车辆或机器人不同位置的传感器,以确保它们生成的点云在同一坐标系统中。 以下是对代码及其实现的标定方法的介绍: 利…

linux虚拟化之kvm(一个200行的arm64虚拟机代码)

一、背景 之前介绍了X86上的一个简易虚拟机&#xff1a; linux虚拟化之kvm&#xff08;一个150行的x86虚拟机代码&#xff09;-CSDN博客 &#xff0c;但作为一名嵌入式开发者&#xff0c;还是需要在ARM64上尝试一番&#xff0c;ARM64上的虚拟化和X86还是有很多差异点&#x…

nosql数据库知识点总结

目录 1、什么是nosql数据库&#xff0c;它包括哪些 文档数据库 建数据 哪一种是最简单的 2、什么是文档数据库 3、创建mongodb时默认会建造三个数据库&#xff0c;是哪三个 4、mongodb支持的数据类型有哪些 5、它的常规语句有哪些 6、副本集和分片集有什么作用 复制 …

​​力扣刷MySQL-第九弹(详细讲解)

&#x1f389;欢迎您来到我的MySQL基础复习专栏 ☆* o(≧▽≦)o *☆哈喽~我是小小恶斯法克&#x1f379; ✨博客主页&#xff1a;小小恶斯法克的博客 &#x1f388;该系列文章专栏&#xff1a;力扣刷题讲解-MySQL &#x1f379;文章作者技术和水平很有限&#xff0c;如果文中出…

Spring 事务原理二

该说些什么呢&#xff1f;一连几天&#xff0c;我都沉溺在孤芳自赏的思维中无法自拔。不知道自己为什么会有这种令人不齿的表现&#xff0c;更不知道这颗定时炸弹何时会将人炸的粉身碎骨。好在儒派宗师曾老夫子“吾日三省吾身”的名言警醒了我。遂潜心自省&#xff0c;溯源头以…

20240128-读书带来的影响

我本身不算是一个特别喜欢读书的人&#xff0c;更多的时候其实是为了读书而读书。在坚持每天读了一小时书之后&#xff0c;我发现自身开始慢慢有些变化。是什么时候突然有了这种感悟呢&#xff0c;是最近每周5小时左右的微信读书以及纸质书籍的阅读&#xff0c;让我体会到了读书…