C语言之通讯录的实现(文末有完整代码)

目录

  • 实现思路
  • 通讯录菜单
  • 通讯录的创建
    • 初始化通讯录
  • 添加联系人
  • 打印通讯录
  • 删除联系人
  • 修改通讯录
  • 完整代码
    • test.c
    • contact.c
    • contact.h

实现思路

让我们首先来想想通讯录一般需要哪些功能,最主要的无非6种:增加联系人,删除联系人,搜索联系人,修改联系人,打印通讯录,将联系人分类。这就是我们要实现的几种基本功能,接下来我们就可以开始上手实现代码了

通讯录菜单

这是非常经典的一步,我们创建一个名为test.c的文件,用来完成对通讯录大致流程的编写,首先咱先完成菜单函数

void menu()
{
     
	printf("*******************************");
	printf("****   1.Add    2.Del    ******");
	printf("****   3.Search 4.Modify ******");
	printf("****   5.Show   6.Sort   ******");
	printf("****   0.Exit            ******");
	printf("*******************************");
}

我希望当我们在键盘上敲击一个数字时,该程序就可以实现对应的功能,所以我们就要在添加下列代码

int main()
{
     
	do
	{
     
		int input = 0;
		menu();
		scanf("%d", &input);
		switch (input)
		{
     
		case 1:
			break;
		case 2:
			break;
		case 3:
			break;
		case 4:
			break;
		case 5:
			break;
		case 6:
			break;

		}

	} while()
	return 0;
}

我们用input变量接收一个值,根据input的值来实现对应的功能,我们或许觉得输入123来实现对应功能不够直观,我们为什么不能直接输入ADD,DEL···呢?所以我可以在创建一个枚举

enum Option
{
     
	EXIT,//代表0
	ADD,//代表1
	DEL,//代表2
	SEARCH,//```
	MODIFY,
	SHOW,
	SORT
};

这样我们就可以将上面的代码修改为

int main()
{
     
	do
	{
     
		int input = 0;
		menu();
		scanf("%d", &input);
		switch (input)
		{
     
		case ADD:
			break;
		case DEL:
			break;
		case SEARCH:
			break;
		case MODIFY:
			break;
		case SHOW:
			break;
		case SORT:
			break;

		}

	} while()
	return 0;
}

通讯录的创建

我们再创建第二个文件“contact.h”这是一个头文件,主要用来存放函数的声明,我们把通讯录的创建也放在这里实现,假设我们要创建一个能存放1000人的通讯录,那么显然我们需要一个容量为1000的数组,那么这个数组中的变量类型应该是什么呢?对于联系人这样的复杂对象,用结构体显然是更加合适的。所以让我们先来创建一个结构体,用来存放联系人信息,

struct PeoInfo
{
     
	char name[NAME];
	int age;
	char sex[SEX];
	char tele[TELE];
	char addr[ADDR];
};

为了增强代码可读性,并且方便代码日后的维护,我把数组大小的数字用具有实际意义的字母来代替,所以我们要增加如下定义

#define NAME 20
#define SEX 5
#define TELE 12
#define ADDR 30

以上的代码已经足以描述一位联系人了,但是在实际操作中我们会发现其实联系人的数量也极其重要,所以我们还应该将用户信息和他的编号一起分装在另一个结构体中

struct contact
{
     
	struct PeoInfo data[MAX];
	int sz;
};

这里我依然用字母来代替数字,所以我们还得加上一个定义,

#define MAX 1000

接着我们在test.c文件中创建一个通讯录

struct contact con;

很遗憾的是,当我们创建完这个通讯录后,通讯录con中储存的仍然是一堆随机值,所以我们得先初始化这个通讯录

初始化通讯录

我们需要创建一个函数,而对于函数的实现,我们可以在"contact.c"源文件中进行,让我们创建一个名为ContactInit的函数来完成初始化,那么我们应该给这个函数传递什么参数呢?因为我们希望对这个通讯录本身进行改变,所以我们不希望改变的只是一个形参,因此此时将结构体的地址传过去是合适的,现在让我们来看看代码的实现,我们先在test.c文件中对函数传参

ContactInit(&con);

接着去contact.h中进行函数声明

void ContactInit(struct contact* pc);

然后在contact.c中完成函数的实现

void ContactInit(struct contact* pc)
{
     
	pc->sz = 0;
	memset(pc->data, 0, MAX * sizeof(struct PeoInfo));
}

这样我们就可以把通讯录中的数值初始化了,接下来我们要开始编写通讯录的功能

添加联系人

我们在contact.c文件中进行添加联系人函数的编写,并将此函数命名为AddContact

void AddContact(struct contact* pc)
{
     
	if (pc -> sz == MAX)
	{
     
		printf("通讯录满了\n");
	}
	else
	{
     
		printf("请输入名字:>");
		scanf("%s", pc->data[pc->sz].name);
		printf("请输入年龄:>");
		scanf("%d", &(pc->data[pc->sz].age));
		printf("请输入性别:>");
		scanf("%s", pc->data[pc->sz].sex);
		printf("请输入电话:>");
		scanf("%s", pc->data[pc->sz].tele);
		prinitf("请输入地址:>");
		scanf("%s", pc->data[pc->sz].addr);
		printf("添加成功\n");
		pc->sz++;
	}
}

以此思路,我们可以很简单的将剩下的功能全部写完,接着让我们先来看看通讯录打印

打印通讯录

void ShowContact(struct contact* pc)
{
     
	int i = 0;
	printf("%15s\t%5s\t%8s\t%15s\t%30s\n\n", "name", "age", "sex", "tele", "addr");
	for (i = 0; i < pc->sz; i++)
	{
     
		printf("%15s\t%5d\t%8s\t%15s\t%30s\n",
			pc->data[i].name,
			pc->data[i].age,
			pc->data[i].sex,
			pc->data[i].tele,
			pc->data[i].addr);
	}
}

这里我们使用for循环遍历通讯录的所有联系人并打印

删除联系人

此功能的思路与其它的稍有不同,因为我们希望删除此联系人后,该联系人后面的联系人整体位置向前移动一格

void DelContact(struct contact* pc)
{
     
	char name[NAME] = {
      0 };
	printf("请输入要删除人的名字");
	scanf("%s", &name);
	//查找
	//删除
}

这是该函数的大致框架,我们为了完成这个函数,其核心就是查找和删除两个功能,而对于查找功能,我们会发现在之后的查找和修改功能中都是会用到的,所以我们完全可以将其分装成一个函数

int FindContactByName(struct contact* pc, char name[])
{
     
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
     
		if (strcpy(pc->data[i].name, name) == 0)
		{
     
			return i;
		}
	}
	return -1;
}

当程序找到该联系人时,它返回的i就是该数组元素的下标,下面我们用pos来接收它

void DelContact(struct contact* pc)
{
     
	char name[NAME] = {
      0 };
	printf("请输入要删除人的名字");
	scanf("%s", &name);
	//查找
	int pos = FindContactByName(pc, name);
	//删除
	if (pos == -1)
	{
     
		printf("该联系人不存在\n");
	}
	else
	{
     
		int i = 0;
		for (i = 0; i < pc->sz-1; i++)
		{
     
			pc->data[i] = pc->data[i + 1];
		}
		pc->sz--;
		printf("删除成功\n");
	}
}

当然,这个程序仍有一点缺陷,当这个通讯录中,没有联系人时,程序应该提示我们当前无法删除,所以我们可以加一行代码

if (pc->sz == 0)
	{
     
		printf("通讯录为空,无法删除\n");
		return;
	}

修改通讯录

void ModifyContact(struct contact* pc)
{
     
	char name[NAME] = {
      0 };
	printf("输入要修改人的名字\n");
	scanf("%s", name);
	int pos = FindContactByName(pc, name);
	if (-1 == pos)
	{
     
		printf("要输入的人不存在\n");
	}
	else
	{
     
		printf("请输入名字:>");
		scanf("%s", pc->data[pos].name);
		printf("请输入年龄:>");
		scanf("%d", &(pc->data[pos].age));
		printf("请输入性别:>");
		scanf("%s", pc->data[pos].sex);
		printf("请输入电话:>");
		scanf("%s", pc->data[pos].tele);
		printf("请输入地址:>");
		scanf("%s", pc->data[pos].addr);
	}
}

完整代码

test.c

#include "contact.h"
void menu()
{
     
	printf("*******************************\n");
	printf("****   1.Add    2.Del    ******\n");
	printf("****   3.Search 4.Modify ******\n");
	printf("****   5.Show   0.Exit   ******\n");
	printf("*******************************\n");
}
enum Option
{
     
	EXIT,
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SHOW
};
int main()
{
     
	struct contact con;
	ContactInit(&con);
	int input = 0;
	do
	{
     
		menu();
		scanf("%d", &input);
		switch (input)
		{
     
		case ADD:
			AddContact(&con);
			break;
		case DEL:
			DelContact(&con);
			break;
		case SEARCH:
			SearchContact(&con);
			break;
		case MODIFY:
			ModifyContact(&con);
			break;
		case SHOW:
			ShowContact(&con);
			break;
		default:
			printf("选择错误\n");
		}
	} while (input);
	return 0;
}

contact.c

#include "contact.h"


void ContactInit(struct contact* pc)
{
     
	pc->sz = 0;
	memset(pc->data, 0, sizeof(pc->data));
}

void AddContact(struct contact* pc)
{
     
	if (pc->sz == MAX)
	{
     
		printf("通讯录满了\n");
	}
	else
	{
     
		printf("请输入名字:>");
		scanf("%s", pc->data[pc->sz].name);
		printf("请输入年龄:>");
		scanf("%d", &(pc->data[pc->sz].age));
		printf("请输入性别:>");
		scanf("%s", pc->data[pc->sz].sex);
		printf("请输入电话:>");
		scanf("%s", pc->data[pc->sz].tele);
		printf("请输入地址:>");
		scanf("%s", pc->data[pc->sz].addr);
		printf("添加成功\n");
		pc->sz++;
	}
}
void ShowContact(struct contact* pc)
{
     
	int i = 0;
	printf("%15s\t%5s\t%8s\t%15s\t%30s\n\n", "name", "age", "sex", "tele", "addr");
	for (i = 0; i < pc->sz; i++)
	{
     
		printf("%15s\t%5d\t%8s\t%15s\t%30s\n",
			pc->data[i].name,
			pc->data[i].age,
			pc->data[i].sex,
			pc->data[i].tele,
			pc->data[i].addr);
	}
}
int FindContactByName(const struct contact* pc, char name[])
{
     
	int i = 0;
	for (i = 0; i < pc->sz; i++)
	{
     
		if (strcmp(pc->data[i].name, name) == 0)
		{
     
			return i;
		}
	}
	return -1;
}
void DelContact(struct contact* pc)
{
     
	if (pc->sz == 0)
	{
     
		printf("通讯录为空,无法删除\n");
		return;
	}
	char name[NAME] = {
      0 };
	printf("请输入要删除人的名字");
	scanf("%s", name);
	//查找
	int pos = FindContactByName(pc, name);
	//删除
	if (pos == -1)
	{
     
		printf("该联系人不存在\n");
	}
	else
	{
     
		int i = 0;
		for (i = 0; i < pc->sz-1; i++)
		{
     
			pc->data[i] = pc->data[i + 1];
		}
		pc->sz--;
		printf("删除成功\n");
	}
}
void SearchContact(const struct contact* pc)
{
     
	if (pc->sz == 0)
	{
     
		printf("通讯录为空\n");
		return;
	}
	printf("请输入联系人名字");
	int pos = 0;
	char name[NAME] = {
      0 };
	scanf("%s", name);
	pos = FindContactByName(pc, name);
	if (pos == -1)
	{
     
		printf("查无此人\n");
	}
	else
	{
     
		printf("%15s\t%5s\t%8s\t%15s\t%30s\n\n", "name", "age", "sex", "tele", "addr");
		printf("%15s\t%5d\t%8s\t%15s\t%30s\n",
			pc->data[pos].name,
			pc->data[pos].age,
			pc->data[pos].sex,
			pc->data[pos].tele,
			pc->data[pos].addr);
	}
}
void ModifyContact(struct contact* pc)
{
     
	char name[NAME] = {
      0 };
	printf("输入要修改人的名字\n");
	scanf("%s", name);
	int pos = FindContactByName(pc, name);
	if (-1 == pos)
	{
     
		printf("要输入的人不存在\n");
	}
	else
	{
     
		printf("请输入名字:>");
		scanf("%s", pc->data[pos].name);
		printf("请输入年龄:>");
		scanf("%d", &(pc->data[pos].age));
		printf("请输入性别:>");
		scanf("%s", pc->data[pos].sex);
		printf("请输入电话:>");
		scanf("%s", pc->data[pos].tele);
		printf("请输入地址:>");
		scanf("%s", pc->data[pos].addr);
	}
}

contact.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include 
#include 

#define NAME 20
#define SEX 5
#define TELE 12
#define ADDR 30
#define MAX 1000
struct PeoInfo
{
     
	char name[NAME];
	int age;
	char sex[SEX];
	char tele[TELE];
	char addr[ADDR];
};

struct contact
{
     
	struct PeoInfo data[MAX];
	int sz;
};

void ContactInit(struct contact* pc);
void AddContact(struct contact* pc);
void ShowContact(struct contact* pc);
void DelContact(struct contact* pc);
void SearchContact(const struct contact* pc);
void ModifyContact(struct contact* pc);

你可能感兴趣的