结构体应用--通讯录

在上一篇文章中我们详细讲解了自定义类型,这篇文章我们就使用结构体实现一个简单的通讯录。

数据的存储

通讯录要存储每个联系人的信息,每个联系人的信息又由姓名,年龄,性别,电话,地址这五个因素组成,所以我们首先要创建一个结构体类型来保存每个联系人的信息。我们在头文件中声明一个People的结构体。这样一个人的信息存储方式就有了,然后我们还需要创建一个结构体来存储我们的通讯录,通讯录首先要有一个数组,整个数组的每个成员都是People的,然后我们还需要一个count变量来记录联系人的总数,因为后续我们要显示结构体和排序结构体都要用到联系人数量。所以我们再声明一个结构体类型Contact,这个结构体有两个成员,一个结构体数组,长度为100,我们用#define来定义一个MAX表示联系人的最大数量,也就是我们的结构体的数组的大小,方便后续修改结构体数组大小,另一个成员变量是count用来记录联系人数量。

#pragma once

#include<stdio.h>
#include<assert.h>

#define MAX 100
typedef struct People
{
	char name[20];
	int age;
	char sex[5];
	char tele[15];
	char address[20];
}People;

typedef struct Contact
{
	People data[MAX];
	size_t count;
}Contact;

菜单以及通讯录初始化

我们需要一个菜单来让用户选择要进行的操作,增删查改排序显示和退出,我们都要在菜单中显示出来,在用户进行操作之前,我们还要对体现了进行初始化,否则通讯录里面都是一些随机值,将count初始化为0;

#include"contact.h"

void Menu()
{
	printf("*******************************\n");
	printf("***** 1.Add      2.Delete *****\n");
	printf("***** 3.Search   4.Modify *****\n");
	printf("***** 5.Sort     6.Show   *****\n");
	printf("******0.Exit              *****\n");
	printf("*******************************\n");
}
void Init_Contact(Contact* pc)
{
	int i = 0;
	for (i = 0; i < MAX; i++)
	{
		*((pc->data[i]).name) = 0;
		(pc->data[i]).age = 0;
		*((pc->data[i]).sex) = 0;
		*((pc->data[i]).tele) = 0;
		*((pc->data[i]).address) = 0;
	}
	pc->count = 0;

}


int main()
{
	int input = 0;
	Contact contact;
	Init_Contact(&contact);
	do
	{
		Menu();
		printf("请选择_>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			//增加联系人
			break;
		case 2:
			//删除联系人
			break;
		case 3:
			//查找联系人
			break;
		case 4:
			//修改联系人
			break;
		case 5:
			//排序联系人
			break;
		case 6:
			//显示联系人
			break;
		case 0:
			//退出
			printf("退出通讯录\n");
			break;
		default:
			printf("选择错误,请重新选择:\n");
			break;
		}

	} while (input);

	return 0;
}

增加联系人

当用户选择增加联系人时,我们需要调用Add_Contact函数,在这个函数中,首先需要用户输入联系人的五项信息,如果增加成功,打印提示信息,如果容量满了,打印提示信息。

void Add_Contact(Contact* pc)
{
	assert(pc);
	if (pc->count <= MAX)
	{
		printf("请输入姓名:");
		scanf("%s", pc->data[pc->count].name);
		printf("请输入年龄:");
		scanf("%d", &(pc->data[pc->count].age));
		printf("请输入性别:");
		scanf("%s", pc->data[pc->count].sex);
		printf("请输入电话:");
		scanf("%s", pc->data[pc->count].tele);
		printf("请输入地址:");
		scanf("%s", pc->data[pc->count].address);
		(pc->count)++;
		printf("增加完成\n");
	}
	else
	{
		printf("联系人已满,请删除一些联系人\n");
	}
}

显示联系人

因为我们后面的的代码的测试都要显示联系人列表来观察,所以我们把这个函数实现在前面以便于我们测试程序是否正常运行。

显示联系人只需要我们循环打印count个联系人的信息出来就行了。

void Show_Contact(Contact* pc)
{
	assert(pc);
	int i = 0;
	printf("姓名          年龄    性别     电话          地址\n");
	for (i = 0; i < pc->count; i++)
	{
		printf("%-15s %-5d %-5s %-15s %-20s\n", 
			pc->data[i].name,
			pc->data[i].age,
			pc->data[i].sex,
			pc->data[i].tele, 
			pc->data[i].address);
	}
}

查找联系人

因为在删除和修改联系人时我们也要用到查找联系人这个函数,所以我们先实现查找联系人。

查找联系人函数的设计我们采用按名字查找,然后遍历整个联系人列表,通过strcmp函数的返回值来判断是否是所查找的联系人,我们在这个函数可以给一个返回值,用于删除函数的使用,我们可以要查找返回联系人的下标。

//具体查找的函数
int Find_By_Name(Contact* pc, char* findname)
{
	assert(pc);
	int i = 0;
	for (i = 0; i < pc->count; i++)
	{
		if (strcmp(pc->data[i].name
			, findname) == 0)
		{
			//找到就直接返回
			return i;
		}
	}
	//遍历完了没有返回则说明找不到
	return -1;//返回-1表示找不到
}

//查找功能的函数
void  Search_Contact(Contact* pc)
{
	assert(pc);
	int i = 0;
	printf("请输入要查找的联系人姓名:");
	char search_name[20] = { 0 };
	scanf("%s", search_name);
	int ret = Find_By_Name(pc, search_name);
	if (ret == -1)
	{
		printf("找不到该联系人\n");
	}
	else
	{
		printf("%-15s %-5d %-5s %-15s %-20s\n",
			pc->data[ret].name,
			pc->data[ret].age,
			pc->data[ret].sex,
			pc->data[ret].tele,
			pc->data[ret].address);
	}
}

删除联系人

删除联系人的函数逻辑也十分简单,首先要通过前面的查找函数来找到要删除联系人的下标,然后从这个下标开始,后面的数据往前面覆盖,最末尾的一个数据我们可以删也可以不删,因为我们会让count-1,所以最末尾的那个数据无所谓。

void Delete_Contact(Contact* pc)
{
	assert(pc);
	char delete_name[20] = { 0 };
	printf("请输入要删除的联系人姓名:");
	scanf("%s", delete_name);
	int ret = Find_By_Name(pc,delete_name);
	if (ret == -1)
	{
		printf("找不到要删除的联系人\n");
	}
	else
	{
		int i = 0;
		for (i = ret; i < pc->count - 1; i++)
		{
			pc->data[i] = pc->data[i + 1];
		}
		pc->count--;
		printf("删除成功\n");
	}
}

修改联系人

修改联系人的逻辑和删除联系人相同,先找到下标,再进行修改,修改就是让用户重新输入一个信息。

//修改联系人
void Modify_Contact(Contact* pc)
{
	assert(pc);
	if (pc->count == 0)
	{
		printf("当前无联系人\n");
		return;
	}
	char modify_name[20] = { 0 };
	printf("请输入要修改的联系人名字;");
	scanf("%s", modify_name);
	int ret = Find_By_Name(pc, modify_name);
	if (ret == -1)
	{
		printf("找不到该联系人\n");
	}
	else
	{
		printf("请重新输入修改后的联系人信息\n");
		printf("请输入姓名:");
		scanf("%s", pc->data[ret].name);
		printf("请输入年龄:");
		scanf("%d", &(pc->data[ret].age));
		printf("请输入性别:");
		scanf("%s", pc->data[ret].sex);
		printf("请输入电话:");
		scanf("%s", pc->data[ret].tele);
		printf("请输入地址:");
		scanf("%s", pc->data[ret].address);
		printf("修改完成\n");
	}
}

排序联系人

排序联系人这个函数我们可以用库里面的qsort函数来实现。

//qsort的比较函数,按名字排序
int cmp_by_name(const void* a, const void* b)
{
	assert(a && b);
	return strcmp( ((People*)a)->name, ((People*)b)->name);
}

//排序联系人
void Sort_Contact(Contact* pc)
{
	assert(pc);
	qsort(pc->data, pc->count, sizeof(People), cmp_by_name);
	printf("排序成功\n");
}

这样一个简单的通讯录就实现了,目前我们的通讯录联系人数量是固定的,而且每次退出程序后联系人的信息就销毁了,说明我们的通讯录还不是最终版本,后续更新完动态内存分配和文件操作后还会有两个升级的版本。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值