通讯录(静态)

引言

如果要用C语言实现通讯录的话,我们需要知道要实现什么功能。对于通讯录来说,除了初始化,就为最基本的增删查改,我就开始一一讲解。

步骤

我们创建文件时,因为代码比较多,为了不使代码冗余。我们需要创建一个用来执行通讯录的源文件,然后就是执行通讯录内部函数代码的源文件,再创建一个用来存放内部函数声明的头文件。

c9034489bd594bbab765a817f9ba71bf.png

首先是通讯录的初始化,由于通讯录需要存储多种数据,所以我是使用结构体类型。

#pragma once
#include<stdio.h>
#include<string.h>
#define MAX 100
#define NA_MAX 20
#define SE_MAX 5
#define ADDR_MAX 20
#define TEL_MAX 12
typedef struct PeoInfo
{
	char name[NA_MAX];
	int age;
	char sex[SE_MAX];
	char addr[ADDR_MAX];
	char tel[TEL_MAX];
}PeoInfo;
//姓名 年龄 性别 地址 电话
typedef struct Conatct
{
	PeoInfo data[MAX];//存放的信息
	int size;//当前存放信息的个数
}Conatct;
void InitContact(Conatct* pc);
void AddContact(Conatct* pc);
void DelContact(Conatct* pc);
void SerachContact(const Conatct* pc);
void ModiftyContact(Conatct* pc);
void SortContact(Conatct* pc);
void ShowContact(const Conatct* pc);

9b0dbca76f51492ca16d2e819696cc1a.png

为了方便修改,其中的大小使用宏来替换。typedef的作用是改变类型名称,这样方便之后的书写。

我们的通讯录肯定是需要记住存储数据的个数,从而判断是否还有数据,并且是否超出数据的最大存储量,因此我们再使用一个结构体对其进行封装。

1666a4ecdb7746f68f03315e190fef4a.png

接下来,我们创建大概的整体逻辑,创建一个简单的菜单用来表明每个功能如何使用。

057b98b5483d4fbfb84fb430b43fc883.png

再整体的逻辑中我们的通讯录一定不可能只用一次,所以整体是以循环实现的。

#include"contact.h"
void menu()
{
	printf("***********************************\n");
	printf("****   1.add        2.del      ****\n");
	printf("****   3.search     4.modify   ****\n");
	printf("****   5.show       6.sort     ****\n");
	printf("****   0.exit                  ****\n");
	printf("***********************************\n");
}
int main()
{
	int input = 0;
	Conatct con;
	InitContact(&con);
	do {
		menu();
		printf("请输入数字\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			AddContact(&con);
			break;
		case 2:
			DelContact(&con);
			break;
		case 3:
			SerachContact(&con);
			break;
		case 4:
			ModiftyContact(&con);
			break;
		case 5:
			ShowContact(&con);
			break;
		case 6:
			SortContact(&con);
			break;
		case 0:
			printf("退出通讯录");
			break;
		default :
			printf("选择错误");
			break;
		}

	} while (input);
	return 0;
}

通过循环来实现遍历,通过switch语句,来实习各个函数的功能。

先实现数据的初始化。

void InitContact(Conatct* pc)
{
	pc->size = 0;
	memset(pc->data, 0, sizeof(pc->data));
}

通过以上代码,数据个数为零,并将通讯录进行初始化,。

void AddContact(Conatct* pc)
{
	if (pc->size == MAX)
	{
		printf("通讯录已满\n");
		return;
	}
	printf("请输入姓名:\n");
	scanf("%s", pc->data[pc->size].name);
	printf("请输入年龄:\n");
	scanf("%d", &pc->data[pc->size].age);
	printf("请输入性别:\n");
	scanf("%s", pc->data[pc->size].sex);
	printf("请输入住址:\n");
	scanf("%s", pc->data[pc->size].addr);
	printf("请输入电话:\n");
	scanf("%s", pc->data[pc->size].tel);
	printf("增加成功\n");
	pc->size++;
}

这个函数是用来实现增加代码的操作,首先我们需要判断一下通讯录是否已满,如果通讯录已经变慢,那么便无法增加数据,直接返回return。如果可以就通过scanf函数来实现数据的增加,最后再对size++表明数据加1。

int SerachName(Conatct* pc, char name[])
{

	int i = 0;
	for (i = 0; i < pc->size; i++)
	{
		if (strcmp(pc->data[i].name,name) == 0)
		{
			return i;
		}
	}
	return -1;
}

我们在后面的编写代码中发现,删、查、改我们都需要用到找。所以我们为什么不方便封装一个函数使用呢。这个函数传参有通讯录结构体的地址和需要找到的姓名,如果没有找到我们就返回-1,如果找到的话我们就返回其下标也就是i,姓名是字符串,字符串之间的比较我们可以用到strcmp函数来执行。

void DelContact(Conatct* pc)
{
	
	int i = 0;
	char name[NA_MAX] = { 0 };
	printf("请输入名字:\n");
	scanf("%s", name);
	int pos = SerachName(pc,name);
	if (pos == -1)
	{
		printf("没有可删除的数据\n");
		return;
	}
	else
	{
		for (i = pos; i < pc->size - 1; i++)
		{
			pc->data[i] = pc->data[i + 1];
		}
	}
	pc->size--;
	printf("删除成功\n");
}

实现通讯录的删除操作,首先我们需要找到需要我们删除的人的姓名,调用上面封装好的寻找姓名的代码即可,找到之后就需要进行删除操作,我们选择的方式是用后面的代码对删除的代码进行覆盖,使用循环从而实现删除操作,由于我们是将i+1的覆盖到i,所以小于size-1,因为如果小于size的情况下会造成越界的错误。

void SerachContact(const Conatct* pc)
{
	char name[NA_MAX] = { 0 };
	printf("请输入名字:\n");
	scanf("%s", name);
	int pos = SerachName(pc,name);
	if (pos == -1)
	{
		printf("没有找到数据\n");
		return;
	}
	else
	{
		printf("寻找成功\n");
		printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", pc->data[pos].name,
			pc->data[pos].age,
			pc->data[pos].sex,
			pc->data[pos].addr,
			pc->data[pos].tel);
	}
}

实现通讯录的查找操作,同样调用上面封装好的寻找姓名的代码,找到知道将其打印出来即可。

void ModiftyContact(Conatct* pc)
{
	char name[NA_MAX] = { 0 };
	printf("请输入要修改的名字:\n");
	scanf("%s", name);
	int pos = SerachName(pc, name);
	if (pos == -1)
	{
		printf("没有找到数据\n");
		return;
	}
	else
	{
		printf("请输入姓名:\n");
		scanf("%s", pc->data[pos].name);
		printf("请输入年龄:\n");
		scanf("%d", &pc->data[pos].age);
		printf("请输入性别:\n");
		scanf("%s", pc->data[pos].sex);
		printf("请输入住址:\n");
		scanf("%s", pc->data[pos].addr);
		printf("请输入电话:\n");
		scanf("%s", pc->data[pos].tel);
		printf("修改成功\n");
	}
}

实现通讯录的修改操作,同样调用上面封装好的寻找姓名的代码,很明显这样的分装使我们的代码更加具有逻辑性。找到之后通过pos直接将其修改即可。

void SortContact(Conatct* pc)
{
	int i = 0;
	PeoInfo tmp;
	for (i = 0; i < pc->size-1; i++)
	{
		int j = 0;
		for (j = 0; j < pc->size - i - 1; j++)
		{
			if (strcmp(pc->data[j].name,pc->data[j+1].name)>0)
			{
				tmp = pc->data[j];
				pc->data[j] = pc->data[j + 1];
				pc->data[j + 1] = tmp;
			}
		}
	}
	printf("排序成功\n");
}

排序的实现我使用了冒泡排序的方法,使用了临时变量,通过strcmp来进行比较名字的大小从而进行交换。

void ShowContact(const Conatct* pc)
{
	printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\n","姓名","年龄","性别","住址","电话");
	int i = 0;
	for (i = 0; i < pc->size; i++)
	{
		printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", pc->data[i].name,
			pc->data[i].age,
			pc->data[i].sex,
			pc->data[i].addr,
			pc->data[i].tel);
	}
}

最后是对通讯录展示也就是打印操作,通过循环遍历从而打印出所以的数据。而%后面的负数是为了使其对齐美观。

结语

静态通讯的实现并不是十分的复杂,只要学会对每一个功能的实现,相信你也可以成功。

 

  • 24
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值