首页 > 其他分享 >通讯录(顺序表的应用)

通讯录(顺序表的应用)

时间:2024-04-06 18:00:31浏览次数:20  
标签:顺序 void 联系人 Contact 通讯录 应用 printf con

文章目录

顺序表思想实现通讯录

实现通讯录前,我们考虑一下,通讯录需要包含什么内容?

联系人,联系人需要包含姓名年龄电话性别这3种基本信息。

我们知道顺序表实质是个数组,如果我们让数组的每个元素都代表一个联系人,每个联系人又需要包含多条信息,所以,我们想到结构体,让数组的每个元素都是结构体,结构体就能很好地描述每一个联系人。

对于这样一个通讯录,我们采用顺序表的思想,但不单独写顺序表的接口,直接实现通讯录的接口,从无到有。

头文件

头文件的书写主要注意以下事项:

  • 结构体的声明
  • 命名的可读性,便于理解
  • 需要哪些对通讯录操作,声明出对应函数
//Contact.h

#pragma once
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>

#define MAX_NAME 20
#define MAX_GENDER 10
#define MAX_TELNUM 20

typedef struct personinfo
{
	char name[MAX_NAME];
	size_t age;
	char telnum[MAX_TELNUM];
	char gender[MAX_GENDER];
}peoinfo;

typedef struct Contact
{
	peoinfo* a;
	int size;
	int capacity;
}Contact;

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

//添加联系人
void ContactAdd(Contact* con);

//删除联系人
void ContactDel(Contact* con);

//修改联系人
void ContactModify(Contact* con);

//展示通讯录
void ContactShow(Contact* con);

//查找联系人信息
void ContactFind(Contact* con);

//销毁通讯录
void ContactDestory(Contact* con);

接口函数

注意:

  • 函数实现要包含必要的语句说明
  • 函数主体部分为顺序表的增删查改
//Contact.c

# define _CRT_SECURE_NO_WARNINGS 1
#include "Contact.h"

void ContactInit(Contact* con)
{
	assert(con);
	con->a = NULL;
	con->size = 0;
	con->capacity = 0;
}


void ContactAdd(Contact* con)
{
	assert(con);
	peoinfo new;
	printf("请输入新联系人的姓名:\n");
	scanf("%s", new.name);
	printf("请输入新联系人的年龄:\n");
	scanf("%zd", &new.age);
	printf("请输入新联系人的电话:\n");
	scanf("%s", new.telnum);
	printf("请输入新联系人的性别:\n");
	scanf("%s", new.gender);
	if (con->size == con->capacity)
	{
		int newcapacity = con->capacity == 0 ? 4 : con->capacity * 2;
		peoinfo* tmp = (peoinfo*)realloc(con->a, sizeof(peoinfo) * newcapacity);
		if (NULL == tmp)
		{
			printf("add error!REASON: realloc function failed!\n");
			exit(-1);
		}
		con->a = tmp;
		con->capacity = newcapacity;
	}
	con->a[con->size] = new;
	con->size++;
}


int FindIndex(Contact* con, char* obj)
{
	for (int i = 0; i < con->size; i++)
	{
		if (0 == strcmp(con->a[i].name, obj))
			return i;
	}
	return -1;
}
void ContactDel(Contact* con)
{
	assert(con);
	char del[MAX_NAME] = { 0 };
	printf("请输入要删除的联系人的姓名:\n");
	scanf("%s", del);
	int ret = FindIndex(con, del);
	if (ret < 0)
	{
		printf("您要删除的联系人不存在!\n");
		return;
	}
	else
	{
		for (int i = ret; i < con->size - 1; i++)
		{
			con->a[i] = con->a[i + 1];
		}
		con->size--;
		printf("删除成功!\n");
	}
}


void ContactModify(Contact* con)
{
	assert(con);
	char mod[MAX_NAME] = { 0 };
	printf("请输入要修改的联系人的姓名:\n");
	scanf("%s", mod);
	int ret = FindIndex(con, mod);
	if (ret < 0)
	{
		printf("您要修改的联系人不存在!\n");
		return;
	}
	else
	{
		char newmod[MAX_NAME] = { 0 };
		size_t newage = 0;
		char newtelnum[MAX_TELNUM] = { 0 };
		char newgender[MAX_TELNUM] = { 0 };

		printf("请输入新的联系人姓名:\n");
		scanf("%s", con->a[ret].name);

		printf("请输入新的联系人年龄:\n");
		scanf("%zd", &con->a[ret].age);

		printf("请输入新的联系人电话:\n");
		scanf("%s", con->a[ret].telnum);

		printf("请输入新的联系人性别:\n");
		scanf("%s", con->a[ret].gender);
		printf("修改成功!\n");
	}

}


void ContactShow(Contact* con)
{
	assert(con);
	if (con->size == 0)
	{
		printf("通讯录为空!\n");
		return;
	}
	else
	{
		printf("----------------------------------------------------------------------------------\n");
		printf("%-11s %-11s %-11s %-11s\n", "姓名", "年龄", "电话", "性别");
		for (int i = 0; i < con->size; i++)
		{
			printf("%-11s %-11zd %-11s %-11s\n", con->a[i].name, con->a[i].age, con->a[i].telnum, con->a[i].gender);
		}
		printf("----------------------------------------------------------------------------------\n");
	}
}


void ContactFind(Contact* con)
{
	assert(con);
	char find[MAX_NAME] = { 0 };
	printf("请输入要查询的联系人的姓名:\n");
	scanf("%s", find);
	int ret = FindIndex(con, find);
	if (ret < 0)
	{
		printf("您要查询的联系人不存在!\n");
		return;
	}
	else
	{
		printf("查询结果如下:\n");
		printf("%-11s %-11s %-11s %-11s\n", "姓名", "年龄", "电话", "性别");
		printf("%-11s %-11zd %-11s %-11s\n", con->a[ret].name, con->a[ret].age, con->a[ret].telnum, con->a[ret].gender);
	}
}


void ContactDestory(Contact* con)
{
	assert(con);
	con->size = con->capacity = 0;
	free(con->a);
	con->a = NULL;
}

主函数

主函数里也是包含一些函数定义的,包括菜单、加载文件、写入文件。

为了持久化保留数据,我们需要调用我们之前学习过的文件知识,将每次更新的数据写入文件中,每次启动程序前载入历史数据,每次程序终止前写入文件,这样就完成了通讯录。
关于文件知识,小裤儿之前发布过一篇文件管理的博客,介绍了文件管理函数等知识。

//interface.c

# define _CRT_SECURE_NO_WARNINGS 1
#include "Contact.h"

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

void SaveContact(Contact* con)
{
	FILE* pf = fopen("contact.txt", "wb");
	if (NULL == pf)
	{
		perror("fopen");
		return;
	}
	for (int i = 0; i < con->size; i++)
	{
		fwrite(con->a + i, sizeof(peoinfo), 1, pf);
	}
	fclose(pf);
	pf = NULL;
	printf("通讯录数据保存成功!\n");
}

void LoadContact(Contact* con)
{
	FILE* pf = fopen("contact.txt", "rb");
	if (NULL == pf)
	{
		perror("fopen");
		return;
	}
	peoinfo buff;
	while (fread(&buff, sizeof(peoinfo), 1, pf))
	{
		if (con->size == con->capacity)
		{
			int newcapacity = con->capacity == 0 ? 4 : con->capacity * 2;
			peoinfo* tmp = (peoinfo*)realloc(con->a, sizeof(peoinfo) * newcapacity);
			if (NULL == tmp)
			{
				printf("add error!REASON: realloc function failed!\n");
				exit(-1);
			}
			con->a = tmp;
			con->capacity = newcapacity;
		}
		con->a[con->size] = buff;
		con->size++;
	}
	fclose(pf);
	pf = NULL;
	printf("历史数据读取成功!\n");
}

int main()
{
	Contact con;
	ContactInit(&con);
	LoadContact(&con);
	int input = 0;
	do
	{
		menu();
		printf("请输入你想执行的操作:\n");
		scanf("%d", &input);
		switch (input)
		{
		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:
			printf("输入非法,请重新输入!\n");
			break;
		}
	} while (input);
	SaveContact(&con);
	ContactDestory(&con);
	return 0;
}

学好了顺序表后,通讯录的实现较为简单,代码很容易看懂,如果代码实现有难度,可能是顺序表并没有完全理解或者是知识点不够熟练,如果有问题,我很荣幸能在评论区和你一起讨论。


效果如下:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如果觉得界面稍乱,可以通过增加换行、分隔线或清理屏幕解决。

标签:顺序,void,联系人,Contact,通讯录,应用,printf,con
From: https://blog.csdn.net/xiaokuer_/article/details/137385725

相关文章

  • Python 潮流周刊第 45 期(摘要)+ 赠书 5 本《Python语言及其应用(第2版)》
    本周刊由Python猫出品,精心筛选国内外的250+信息源,为你挑选最值得分享的文章、教程、开源项目、软件工具、播客和视频、热门话题等内容。愿景:帮助所有读者精进Python技术,并增长职业和副业的收入。周刊全文:https://pythoncat.top/posts/2024-04-06-weekly特别提醒:本期赠书5......
  • 快递费用一目了然:taobao.item_fee API在电商中的应用
    taobao.item_feeAPI在电商中的应用主要体现在精准计算快递费用,从而为用户提供一个更加透明和便捷的购物体验。这一接口允许淘宝或天猫的开发者根据商品ID、收货地址等信息,精确计算商品的快递费用。对于用户而言,这意味着在购物过程中能够实时获得运费的估算,从而做出更明智的购......
  • 实景三维在园区管理领域的应用
    随着信息技术的突飞猛进,实景三维技术如同一把神奇的钥匙,逐渐解锁了园区管理领域的新天地。本文将带您领略实景三维技术的独特魅力,并深入探究其在园区管理中的重要地位。一、揭开实景三维技术的神秘面纱实景三维技术,又称为三维实景建模技术,它如同一位精细的画家,将现实世界的场......
  • 开源模型应用落地-qwen1.5-7b-chat-LoRA微调代码拆解
    一、前言  本篇文章将解析QWen1.5系列模型的微调代码,帮助您理解其中的关键技术要点。通过阅读本文,您将能够更好地掌握这些关键技术,并应用于自己的项目中。   开源模型应用落地-qwen1.5-7b-chat-LoRA微调(二)二、术语介绍2.1.LoRA微调  LoRA(Low-RankAdap......
  • 两个顺序表的合并问题
    两个顺序表的合并问题#include<stdio.h>#defineMAXSIZE300typedefstruct{ intlength; int*p;}Sqlist;voidSXB(Sqlist&L){ L.length=0; L.p=newint[MAXSIZE];}voidinsert(Sqlist&L,intn){ if(n>MAXSIZE)printf("inputerror!"); in......
  • 数据结构之顺序表的相关知识点及应用
     个人主页(找往期文章包括但不限于本期文章中不懂的知识点):我要学编程(ಥ_ಥ)-CSDN博客目录顺序表的概念及结构顺序表的分类顺序表的实现 在顺序表中增加数据 在顺序表中删除数据 在顺序表中查找数据 顺序表源码 顺序表的概念及结构在了解顺序表之前,得先知道......
  • 腾讯云2核4G轻量服务器应用场景详解:2024年5M带宽服务器测评与优惠活动大放送
     随着云计算技术的日益成熟,腾讯云推出的2核4G5M轻量应用服务器已成为众多用户的首选。那么,这款服务器究竟能干什么?适用哪些场景呢?腾讯云2核4G5M轻量应用服务器,凭借其出色的性能与合理的价格,已成为性价比极高的云服务器产品。对于大部分个人使用需求,如网页浏览、在线视频播放......
  • 如何使用GraphQL和Apollo构建一个宝可梦应用
    宝可梦是一个由视频游戏、动画系列与电影、交换卡牌游戏以及其他相关媒体组成的日本媒体特许经营权。在本文中,我们将使用一个宝可梦GraphQLAPI,该API提供有关不同宝可梦的数据。我们将使用Apollo和GraphQL来处理数据获取,以及React来构建我们的前端应用程序。如果您不了解这些技......
  • 精讲AI教程: 免费使用Flowise搭建LLM工作流应用
    大家好,我是斜杠君。今天,和大家分享一个低代码/无代码拖放工具——Flowise,可以让你轻松可视化和构建LLM应用程序。  什么是Flowise? 官方定义:Flowise是一种低代码/无代码拖放工具,旨在让人们轻松可视化和构建LLM应用程序。 斜杠君解释:就是把各模块拖拽组合在一起,组......
  • 常用软件架构模式优缺点及应用场景
     1、分层架构模式最常见的架构模式就是分层架构或者称为n层架构。大部分软件架构师、设计师和开发者都对这个架构模式非常熟悉。尽管对于层的数量和类型没有具体限制,但大部分分层架构主要由四层组成:展现层、业务层、持久层和数据库层,如下图所示。一个很流行的n层架构示......