首页 > 其他分享 >通讯录实现!(基于顺序表的项目)

通讯录实现!(基于顺序表的项目)

时间:2024-03-20 23:29:05浏览次数:22  
标签:ps 基于 顺序 void arr pos 通讯录 size con

一.通讯录实现要求

c语言基础要求:结构体、动态内存管理、顺序表、文件操作

二、通讯录功能

能够保存用户信息、能够增加联系人、删除联系人、查找联系人、修改联系人信息、显示联系人信息

三、通讯录实现

通讯录实现90%是基于之前的顺序表的,所以想要实现通讯录可以先去看看我有一篇顺序表的博客(很细很细)

//头文件SeqList.h和contact.h

#pragma once
//SeqList.h
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include "contact.h"
typedef struct PersonInfo SLDataType;
typedef struct SeqList
{
	SLDataType* arr; //动态内存管理
	int size;    //有效数据个数
	int capacity;//空间大小
}SL;

//顺序表的初始化与销毁
void SLInit(SL* ps);
void SLDestroy(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);

//查找数据
void SLFind(SL* ps, SLDataType x);


//打印顺序表->进行测试功能
void SLPrint(SL* ps);
#pragma once
//contact.h
#include "SeqList.h"

#define NAME_MAX 50
#define SEX_MAX 15
#define TEL_MAX 50
#define ADDR_MAX 50
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 ConInit(contact* con);
void ConDestory(contact* con);


//添加联系人
void ConAdd(contact* con);

//删除联系人
void DelContact(contact* con);

//打印联系人
void ConPrint(contact* con);

//查找联系人
void ConFind(contact* con);

//修改联系人信息
void ModifyContact(contact* con);

//实现文件SeqList.c与contact.c

#define _CRT_SECURE_NO_WARNINGS 1
//SeqList.c
#include "SeqList.h"

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

}

//检查空间是否充足
void SLCheckCapacity(SL* ps)
{
	if(ps->capacity==ps->size)
		{
		int newCapacity = ps->capacity == 0 ? 4 : 2 * (ps->capacity);
		//初始化时capacity是0 若我们直接写 capacity*=2; 那空间大小就是0*2==0;
		//所以用一个三目运算符判断capacity是否为0
		//若为0 --- 多给点 给个4 ,若不是0,正常扩大2倍(也可以是1.5倍/1.25倍数等等等等)
		//开始扩大空间
		SLDataType* tmp = (SLDataType*)realloc(ps->arr, sizeof(ps) * newCapacity);
		//记得写sizeof(ps),要不然只扩大4个比特
		if (tmp == NULL)//防止扩大失败返回空指针
		{
			perror("realloc");
			exit(1);
		}
		ps->arr = tmp;
		ps->capacity = newCapacity;
		}
}

//顺序表的头部插入与尾部插入
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];
			//最后:arr[1] = arr[0]
		}
		ps->arr[0] = x;
	    ps->size++;
}


void SLPushBack(SL* ps,SLDataType x)
{
	assert(ps);

		SLCheckCapacity(ps);

	//空间经过检查足够,开始尾部插入
	ps->arr[ps->size] = x;
	ps->size++;

}

//顺序表的头部删除与尾部删除
void SLPopFront(SL* ps)
{
	assert(ps);
	//既然要删除,就不能传空数组
	assert(ps->size);
	for (int i = 0; i < ps->size - 1; i++)
	{
		//arr[size-2] = arr[size-1];
		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);
	SLCheckCapacity(ps);
	//注意对pos也有要求,pos必需>=0 &&pos<=size,可以向等,因为空间是足够的,经过检查后,capacity>size
	assert(pos >= 0 && pos <= ps->size);
	for (int i =ps->size;i>pos;i-- )
	{
		//arr[pos+1] = arr[pos];
		ps->arr[i] = ps->arr[i-1];
	}
	ps->arr[pos] = x;
	ps->size++;
}
//删除当前位置数据
void SLErase(SL* ps, int pos)
{
	assert(ps);
	assert(pos >= 0 && pos < ps->size);//这次不能等于size了,size位置并没有数据
	for (int i = pos; i<ps->size-1;i++)
	{
		ps->arr[i] = ps->arr[i+1];
		//arr[pos] = arr[pos+1]
	}
	ps->size--;
}

//查找数据
//void SLFind(SL* ps, SLDataType x)
//{
//	assert(ps);
//	int b = -1;
//	for (int i = 0; i < ps->size; i++)
//	{
//		if (ps->arr[i] == x)
//		{
//			printf("%d ", i);
//			b = 1;
//		}
//	}
//	if (b == -1)
//	{
//		printf("找不到该数据\n");
//	}
//}

void SLDestroy(SL* ps)
{
	assert(ps);
	//但如果arr还没有被分配空间(初始时),就无需释放空间了
	if (ps->arr != NULL)
	{
		free(ps->arr);
	}
	ps->arr = NULL;
	ps->capacity = ps->size = 0;
	//ps是函数的临时变量,系统自动销毁,那边传过来的的不是指针的地址,而是&sl,即结构体的地址
}

//顺序表的打印
void SLPrint(SL* ps)
{
	for (int i = 0; i < ps->size; i++)
	{
		printf("%s %s %d %s %s \n", ps->arr[i].name,ps->arr[i].sex,ps->arr[i].age,ps->arr[i].tel,ps->arr[i].addr);
	}
	//注意,这里用%d只是因为SLDataType暂时是int
	printf("\n");
}
#define _CRT_SECURE_NO_WARNINGS 1
//contact.h
#include "contact.h"
#include "SeqList.h"


//初始化/销毁通讯录
void ConInit(contact* con)
{
	SLInit(con);

}

//添加联系人
void ConAdd(contact* con)
{
	PeoInfo info;
	printf("请分别输入要添加的联系人的姓名,性别,年龄,电话号码,住址\n");
	scanf("%s %s %d %s %s", info.name, info.sex, &(info.age), info.tel, info.addr);
	SLPushBack(con, info);
}
int FindByName(contact* con,char name[NAME_MAX])
{
	int i = 0;
	for (i = 0; i < con->size; i++)
	{
		if (0 == strcmp(con->arr[i].name, name));
		{
			return i;
		}
	}
	return -1;
}

//删除联系人
void DelContact(contact* con)
{
	char name[NAME_MAX];
	printf("请输入您要删除的联系人的姓名\n");
	scanf("%s", name);
	int pos = FindByName(con,name);
	if (pos==-1)
	{
		printf("名字输入错误或联系人和不存在\n");
	}
	else
	{
		SLErase(con, pos);
		printf("已删除\n");
	}
}

//打印联系人
void ConPrint(contact* con)
{
	if (con->size == 0)
	{
		printf("还没有联系人\n");
	}
	SLPrint(con);
}
//查找联系人
void ConFind(contact* con)
{
	char name[NAME_MAX];
	printf("请输入要查找的联系人姓名\n");
	scanf("%s", name);
	int pos = FindByName(con, name);
	if (pos == -1)
	{
		printf("要查找的联系人不存在!\n");
	}
	else
	{
		printf("%s %s %d %s %s\n", 
			con->arr[pos].name, 
			con->arr[pos].sex,
			con->arr[pos].age,
			con->arr[pos].tel,
			con->arr[pos].addr);
	}
}

//修改联系人信息
void ModifyContact(contact* con)
{
	char name[NAME_MAX];
	
	printf("请输入要修改的联系人姓名\n");
	scanf("%s", name);
	int pos = FindByName(con, name);
	if (pos == -1)
	{
		printf("要查找的联系人不存在!\n");
	}
	else
	{
		printf("请输入要改动的信息\n");
		scanf("%s %s %d %s %s", con->arr[pos].name,
			con->arr[pos].sex,
			&(con->arr[pos].age),
			con->arr[pos].tel,
			con->arr[pos].addr);
		printf("修改完成!");
	}

	}


void ConDestory(contact* con)
{
	SLDestroy(con);
}

//测试文件

#define _CRT_SECURE_NO_WARNINGS 1
//contact test.c
#include"SeqList.h"
#include"contact.h"

void menu()
{
	printf("***************************************\n");
	printf("*****1.添加联系人    2.删除联系人******\n");
	printf("*****3.查找联系人    4.修改联系人******\n");
	printf("*****5.全部联系人    0.退出通讯录******\n");
	printf("***************************************\n");
	
}
int main()
{
	contact con;
	ConInit(&con);
	int ch = 0;
	do
	{
		menu();
		printf("请输入:\n");
		scanf("%d", &ch);
		switch (ch)
		{
		case 1: 
			ConAdd(&con);
			break;
		case 2:
			DelContact(&con);
			break;
		case 3:
			ConFind(&con);
			break;
		case 4:
			ModifyContact(&con);
			break;
		case 5:
			ConPrint(&con);
			break;
		case 0:
			ConDestory(&con);
			break;
		default:
			printf("请重新输入有效数字:\n");
		}

	} while(ch);

	return 0;
}

四、感谢观看,一起进步!

标签:ps,基于,顺序,void,arr,pos,通讯录,size,con
From: https://blog.csdn.net/2301_80464369/article/details/136736535

相关文章

  • 基于springboot实现校园管理系统的设计与实现演示【附项目源码+论文说明】
    基于springboot实现校园管理系统的设计与实现演示摘要随着科学技术的飞速发展,社会的方方面面、各行各业都在努力与现代的先进技术接轨,通过科技手段来提高自身的优势,校园管理系统当然也不能排除在外。校园管理系统是以实际运用为开发背景,运用软件工程原理和开发方法,采用sp......
  • 基于SpringBoot实现旅游网站管理系统项目演示【附项目源码+论文说明】
    基于SpringBoot实现旅游网站管理系统项目演示摘要随着科学技术的飞速发展,各行各业都在努力与现代先进技术接轨,通过科技手段提高自身的优势,旅游网站当然也不能排除在外,随着旅游网站的不断成熟,它彻底改变了过去传统的旅游网站方式,不仅使旅游管理难度变低了,还提升了旅游网站......
  • 基于Springboot的在线装修管理系统(有报告)。Javaee项目,springboot项目。
    演示视频:基于Springboot的在线装修管理系统(有报告)。Javaee项目,springboot项目。项目介绍:采用M(model)V(view)C(controller)三层体系结构,通过Spring+SpringBoot+Mybatis+Vue+Maven+Layui+Elementui来实现。MySQL数据库作为系统数据储存平台,实现了基于B/S结构的Web系统......
  • 基于python+django+Spark的动漫推荐可视化分析系统
    摘 要近年来,随着互联网的蓬勃发展,企事业单位对信息的管理提出了更高的要求。以传统的管理方式已无法满足现代人们的需求。为了迎合时代需求,优化管理效率,各种各样的管理系统应运而生,随着各行业的不断发展,基于Spark的国漫推荐系统的建设也逐渐进入了信息化的进程。这个系统......
  • 基于springboot的考研资讯交流平台
    摘  要随着现在网络的快速发展,网络的应用在各行各业当中它很快融入到了许多学校的眼球之中,他们利用网络来做这个电商的服务,随之就产生了“考研资讯平台”,这样就让学生考研资讯平台更加方便简单。对于本考研资讯平台的设计来说,它主要是采用java技术。在整个系统的设计当中......
  • 基于cnn卷积神经网络的yolov8动物姿态估计识别(训练+代码)
    往期热门博客项目回顾:计算机视觉项目大集合改进的yolo目标检测-测距测速路径规划算法图像去雨去雾+目标检测+测距项目交通标志识别项目yolo系列-重磅yolov9界面-最新的yolo姿态识别-3d姿态识别深度学习小白学习路线基于CNN(卷积神经网络)的YOLOv8模型在动物姿态......
  • java毕业设计基于微信小程序的中药调理系统
    本系统(程序+源码)带文档lw万字以上  文末可领取本课题的JAVA源码参考系统程序文件列表系统的选题背景和意义随着现代生活节奏的加快,人们对于健康问题越来越关注。在众多保健方式中,中药以其独特的调理作用和较少的副作用受到广泛欢迎。然而,中药的种类繁多,配方复杂,普通人往......
  • STM32 HAL库基于F103系列之异步通信
    硬件资源串口1(PA9/PA10连接在板载USB转串口芯片CH340C上面) 原理图USB转串口硬件部分的原理图 程序设计USART/UART异步通信配置步骤1、配置串口工作参数  HAL_UART_Init()2,串口底层初始化  HAL_UART_MspInit()   配置GPIO、NVIC、CLOCK等3,开启串口异步接......
  • 基于深度学习的人员指纹身份识别算法matlab仿真
    1.算法运行效果图预览  2.算法运行软件版本matlab2022a  3.算法理论概述      指纹识别技术是一种生物特征识别技术,它通过分析人类手指末端皮肤表面的纹路特征来进行身份认证。深度学习是机器学习的一个分支,特别适用于处理大规模高维数据,并在图像识别、语......
  • 机器人路径规划:基于迪杰斯特拉算法(Dijkstra)的机器人路径规划(提供Python代码)
    迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题。迪杰斯特拉算法主要特点是从起始点开始,采用贪心算法的策略,每次遍历到始点距离最近且未访问过的顶点的邻......