C语言实现通讯录

目录

一、程序的总线

二、通讯录的简单介绍

三、各个构造函数介绍

1、初始化函数

2、容量检查函数

3、通讯录查询函数

4、打印函数

5、通讯录添加函数

6、通讯录成员删除函数

7、通讯录清除函数

8、通讯录查找函数

9、通讯录成员信息修改函数

10、通讯录排序函数

四、程序代码

1、头文件'utili.h'

2、头文件'Contact.h'

3、源文件'Contact.c'

4、源文件'ContactMain.c'


一、程序的总线

首先我们需要建立两个头文件'utili.h'、'Contact.h',头文件'utili.h'作为公共头文件主要去引用在程序中调用的库函数的头文件,头文件'Contact'进行自定义函数的声明;以及两个源文件'Contact.c'、'ContactMain.c',源文件'Contact.c'主要进行通讯录各个函数功能的实现,源文件'ContactMain.c'作为驱动文件进行程序运行。

二、通讯录的简单介绍

接下来对本次实现的通讯录进行一个简单的介绍,通讯录中个人信息包括姓名、性别、年龄、电话、住址。通讯录共有七个功能,添加、删除、清除、查找、修改、排序、显示,本程序都是通过姓名来实现查找、排序等功能,当然我们也可以通过年龄、性别等实现。通讯录目录如下(输入相应的数字执行对应的功能):

  • 目录如下:
int main()
{
	int select = 1;
	while (select)
	{
		printf("******************************\n");
		printf("**********通 讯 录************\n");
		printf("*[1]Add            [2]Del    *\n");
		printf("*[3]Clear          [4]Find   *\n");
		printf("*[5]Modify         [6]Sort   *\n");
		printf("*[0]Exit           [7]Show   *\n");
		printf("******************************\n");
		printf("请选择:>");
		scanf("%d", &select);
	}
	return 0;
}
  • 显示如下:

三、各个构造函数介绍

这部分是对各个分部函数的介绍,如果有些地方看不懂,可以去后面看一下总体的代码,再回来看这部分。该通讯录默认通过姓名进行查询、排序等。

两个结构体,一个个人信息的结构体,一个通讯录的结构体,方便下面代码的阅读。

//定义信息结构
typedef struct PersonInfo
{
	char name[MAX_NAME_SIZE];
	char sex[MAX_SEX_SIZE];
	int  age;
	char tele[MAX_TELE_SIZE];
	char address[MAX_ADDRESS_SIZE];
}PersonInfo;

//定义通讯录结构
typedef struct Contact
{
	PersonInfo cont[MAX_CONTACT_SIZE];
	size_t capacity;//通讯录总容量
	size_t size;//通讯录当前成员个数
}Contact;

1、初始化函数

在对于通讯录进行一系列操作之前,我们有时候会需要对通讯录进行初始化,需要用到内存函数memset,此时需要在公共头文件中引用头文件<string.h>,代码如下:

void InitContact(Contact *pcnt)//对通讯录进行初始化
{
	memset(pcnt->cont, 0, sizeof(PersonInfo)*MAX_CONTACT_SIZE);
	pcnt->capacity = MAX_CONTACT_SIZE;
	pcnt->size = 0;
}

2、容量检查函数

在进行添加操作前,我们需要对通讯录进行判断是否有空间可以添加,此时需要用到检查通讯录容量的函数,其返回值为bool类型,则需要在公共头文件中引用头文件<stdbool.h>,函数实现如下:

bool IsFull(Contact *pcnt)//检查容量
{
	return pcnt->size >= pcnt->capacity;
}

3、通讯录查询函数

查找时,需要用到字符串比较函数strcmp,如果找到返回下表,没找到返回-1.

int FindByName(Contact *pcnt,char* name)//通过姓名查找
{
	for (int i = 0; i < pcnt->size; ++i)
	{
		if (strcmp(name, pcnt->cont[i].name) == 0)
			return i;
	}
	return -1;
}

4、打印函数

对通讯录信息进行打印时,我们需要考虑一个问题,我们需要打印姓名、性别、电话等信息,那么我们如何能够确保打印出来比较规整,就是信息之间的对齐问题,这个需要重视一下。代码如下·(两个printf在打印时处理了格式的问题):

void ShowContact(Contact *pcnt)
{
	printf("%-8s%-6s%-6s%-13s%s\n", "姓名", "性别", "年龄", "电话", "地址");
	for (int i = 0; i < pcnt->size; ++i)
	{
		printf("%-8s%-6s%-6d%-13s%s\n", pcnt->cont[i].name,
			pcnt->cont[i].sex,
			pcnt->cont[i].age,
			pcnt->cont[i].tele,
			pcnt->cont[i].address);
	}
}

5、通讯录添加函数

在进行通讯录添加时,我们需要先对通讯录的空间进行判断,如果通讯录已满,则无法再进行添加,如果可以添加,依次输入添加信息即可。代码如下:

void AddContact(Contact *pcnt)
{
	//检查容量
	if (IsFull(pcnt))
	{
		printf("通讯录已满,无法进行添加!!!\n");
		return;
	}
	printf("姓名:>");
	scanf("%s", pcnt->cont[pcnt->size].name);
	printf("性别:>");
	scanf("%s", pcnt->cont[pcnt->size].sex);
	printf("年龄:>");
	scanf("%d", &pcnt->cont[pcnt->size].age);
	printf("电话:>");
	scanf("%s", pcnt->cont[pcnt->size].tele); 
	printf("地址:>");
	scanf("%s", pcnt->cont[pcnt->size].address);
	pcnt->size++;
	printf("信息添加成功\n");
}

6、通讯录成员删除函数

在进行通讯录成员删除时,找到成员下标,只需要让后面的成员整体向前覆盖就行,在向前覆盖的时候,我们可以直接结构体给结构体赋值,这样可以节省我们大量的时间,同时,覆盖完成后,通讯录成员个数减一即可。代码如下:

void DelContact(Contact *pcnt)//通讯录成员删除
{
	char name[MAX_NAME_SIZE];
	printf("请输入要删除的成员的姓名:");
	scanf("%s", name);
	int index = FindByName(pcnt, name);
	if (index == -1)
	{
		printf("信息不存在!!!\n");
		return;
	}
	for (int i = index; i < pcnt->size-1; ++i)
	{
		pcnt->cont[i] = pcnt->cont[i + 1];//结构体给结构体赋值
	}
	pcnt->size--;
}

7、通讯录清除函数

清空通讯录时,我们只需要将通讯录成员个数size置零即可,不需要对成员进行初始化,这么做还有一个好处就是如果我们清除后想要恢复,那是不是再给size赋值便可以了呢?代码如下:

void ClearContact(Contact *pcnt)//通讯录清空
{
	printf("是否清空通讯录<Y/N>?\n");
	fflush(stdin);//清除上一次的换行符
	char ch = getchar();
	if (ch == 'N')
	{
		printf("未清空通讯录!\n");
		return;
	}
	else if (ch == 'Y')
	{
		pcnt->size = 0;
		printf("清空通讯录成功!\n");
	}
	else
		printf("输入错误!!!\n");
}

8、通讯录查找函数

查找时,首先我们需要判断通讯录是否为空,如果为空,则无法查找;不为空则需要找到查找信息的下标,对该行信息进行打印,代码如下:

void FindContact(Contact *pcnt)//通讯录查找函数
{
	if (IsEmpty(pcnt))
	{
		printf("通讯录为空,不能查找!!!\n");;
		return;
	}
	char name[MAX_NAME_SIZE];
	printf("请输入查询的姓名:");
	scanf("%s", name);
	int index = FindByName(pcnt,name);
	if (index == -1)
	{
		printf("信息不存在!!!\n");
		return;
	}
	printf("%-8s%-6s%-6d%-13s%s\n", pcnt->cont[index].name,
		pcnt->cont[index].sex,
		pcnt->cont[index].age,
		pcnt->cont[index].tele,
		pcnt->cont[index].address);
}

9、通讯录成员信息修改函数

在进行成员信息修改时,我们需要判断通讯录是否为空,然后找到需要修改信息成员的下标,输入其需要修改的信息进行修改。代码如下:

void ModifyContact(Contact *pcnt)//通讯录成员信息修改
{
	if (IsEmpty(pcnt))
	{
		printf("通讯录为空,不能修改!!!\n");
		return;
	}
	char name[MAX_NAME_SIZE];
	printf("请输入要修改成员的姓名:");
	scanf("%s", name);
	int index = FindByName(pcnt, name);
	if (index == -1)
	{
		printf("修改的成员不存在!!!\n");
		return;
	}
	printf("想要修改什么信息(1-姓名,2-性别,3-年龄,4-电话,5-地址)\n");
	int select;
	scanf("%d", &select);
	switch (select)//switch来进行修改信息的选择
	{
	case 1:
		printf("请输入要修改的姓名:");
		scanf("%s", pcnt->cont[index].name);
		break;
	case 2:
		printf("请输入要修改的性别:");
		scanf("%s", pcnt->cont[index].sex);
		break;
	case 3:
		printf("请输入要修改的年龄:");
		scanf("%d", &pcnt->cont[index].age);
		break;
	case 4:
		printf("请输入要修改的电话:");
		scanf("%s", pcnt->cont[index].tele);
		break;
	case 5:
		printf("请输入要修改的地址:");
		scanf("%s", pcnt->cont[index].address);
		break;
	}
}

10、通讯录排序函数

这里我们可以通过冒泡排序来实现,对于姓名的排序,通过姓名拼字字符串比大小来确定成员的先后顺序。

void SortContact(Contact *pcnt)//通讯录排序
{
	for (int i = 0; i < pcnt->size - 1; ++i)
	{
		for (int j  = 0; j < pcnt->size - i - 1; ++j)
		{
			if (strcmp(pcnt->cont[j].name, pcnt->cont[j + 1].name)>0)
			{
				PersonInfo tmp = pcnt->cont[j];
				pcnt->cont[j] = pcnt->cont[j + 1];
				pcnt->cont[j + 1] = tmp;
			}
		}
	}
	printf("排序成功!\n");
}

四、程序代码

1、头文件'utili.h'

用来存放该程序用到的库函数的头文件。

#ifndef _UTILI_H_
#define _UTILI_H_


#include<stdio.h>
#include<string.h>
#include<stdbool.h>

#endif/*_UTILI_H_*/

2、头文件'Contact.h'

用来存放程序自定义函数的声明、自定义的结构体、定义的宏以及枚举变量

#ifndef _CONTACT_H_
#define _CONTACT_H_

#include"utili.h"

enum{
	Exit,Add,Del,Clear,Find,Modify,Sort,Show//注意顺序与功能相对应
};
#define MAX_NAME_SIZE  20
#define MAX_SEX_SIZE 3
#define MAX_TELE_SIZE 12
#define MAX_ADDRESS_SIZE 256
#define MAX_CONTACT_SIZE 1000
//定义信息结构
typedef struct PersonInfo
{
	char name[MAX_NAME_SIZE];
	char sex[MAX_SEX_SIZE];
	int  age;
	char tele[MAX_TELE_SIZE];
	char address[MAX_ADDRESS_SIZE];
}PersonInfo;
//定义通讯录结构
typedef struct Contact
{
	PersonInfo cont[MAX_CONTACT_SIZE];
	size_t capacity;
	size_t size;
}Contact;

//函数的声明
bool IsFull(Contact *pcnt);//检查通讯录容量
bool IsEmpty(Contact *pcnt);//判断通讯录是否为空
int FindByName(Contact *pcnt,char);//通过姓名查找,返回其下标
void InitContact(Contact *pcnt);//对通讯录进行初始化
void AddContact(Contact *pcnt);//对通讯录进行成员添加
void DelContact(Contact *pcnt);//通讯录成员删除
void clearContact(Contact *pcnt);//通讯录信息清空
void FindContact(Contact *pcnt);//通讯录查找
void ModifyContact(Contact *pcnt);//通讯录成员信息修改
void SortContact(Contact *pcnt);//通讯录排序
void ShowContact(Contact *pcnt);//对通讯录进行打印


#endif /*_CONTACT_H_*/

3、源文件'Contact.c'

用来存放程序中用到的所有自定义函数的主体,所有自定义函数的实现均在其中。

#define _CRT_SECURE_NO_WARNINGS 1
#include"Contact.h"
void InitContact(Contact *pcnt)//对通讯录进行初始化
{
	memset(pcnt->cont, 0, sizeof(PersonInfo)*MAX_CONTACT_SIZE);
	pcnt->capacity = MAX_CONTACT_SIZE;
	pcnt->size = 0;
}
bool IsFull(Contact *pcnt)//检查容量
{
	return pcnt->size >= pcnt->capacity;
}
bool IsEmpty(Contact *pcnt)//判断通讯录是否为空
{
	return pcnt->size == 0;
}
int FindByName(Contact *pcnt,char* name)//通过姓名查找
{
	for (int i = 0; i < pcnt->size; ++i)
	{
		if (strcmp(name, pcnt->cont[i].name) == 0)
			return i;
	}
	return -1;
}
void AddContact(Contact *pcnt)//添加信息
{
	//检查容量
	if (IsFull(pcnt))
	{
		printf("通讯录已满,无法进行添加!!!\n");
		return;
	}
	printf("姓名:");
	scanf("%s", pcnt->cont[pcnt->size].name);
	printf("性别:");
	scanf("%s", pcnt->cont[pcnt->size].sex);
	printf("年龄:");
	scanf("%d", &pcnt->cont[pcnt->size].age);
	printf("电话:");
	scanf("%s", pcnt->cont[pcnt->size].tele); 
	printf("地址:");
	scanf("%s", pcnt->cont[pcnt->size].address);
	pcnt->size++;
	printf("信息添加成功\n");
}
void DelContact(Contact *pcnt)//通讯录成员删除
{
	char name[MAX_NAME_SIZE];
	printf("请输入要删除的成员的姓名:");
	scanf("%s", name);
	int index = FindByName(pcnt, name);
	if (index == -1)
	{
		printf("信息不存在!!!\n");
		return;
	}
	for (int i = index; i < pcnt->size-1; ++i)
	{
		pcnt->cont[i] = pcnt->cont[i + 1];
	}
	pcnt->size--;
	printf("删除信息成功!!!\n");
}
void ClearContact(Contact *pcnt)//通讯录清空
{
	printf("是否清空通讯录<Y/N>?\n");
	fflush(stdin);//清除上一次的换行符
	char ch = getchar();
	if (ch == 'N')
	{
		printf("未清空通讯录!\n");
		return;
	}
	else if (ch == 'Y')
	{
		pcnt->size = 0;
		printf("清空通讯录成功!\n");
	}
	else
		printf("输入错误!!!\n");
}
void FindContact(Contact *pcnt)//通讯录查找函数
{
	if (IsEmpty(pcnt))
	{
		printf("通讯录为空,不能查找!!!\n");;
		return;
	}
	char name[MAX_NAME_SIZE];
	printf("请输入查询的姓名:");
	scanf("%s", name);
	int index = FindByName(pcnt,name);
	if (index == -1)
	{
		printf("信息不存在!!!\n");
		return;
	}
	printf("%-8s%-6s%-6d%-13s%s\n", pcnt->cont[index].name,
		pcnt->cont[index].sex,
		pcnt->cont[index].age,
		pcnt->cont[index].tele,
		pcnt->cont[index].address);
}
void ModifyContact(Contact *pcnt)//通讯录成员信息修改
{
	if (IsEmpty(pcnt))
	{
		printf("通讯录为空,不能修改!!!\n");
		return;
	}
	char name[MAX_NAME_SIZE];
	printf("请输入要修改成员的姓名:");
	scanf("%s", name);
	int index = FindByName(pcnt, name);
	if (index == -1)
	{
		printf("修改的成员不存在!!!\n");
		return;
	}
	printf("想要修改什么信息(1-姓名,2-性别,3-年龄,4-电话,5-地址)\n");
	int select;
	scanf("%d", &select);
	switch (select)
	{
	case 1:
		printf("请输入要修改的姓名:");
		scanf("%s", pcnt->cont[index].name);
		break;
	case 2:
		printf("请输入要修改的性别:");
		scanf("%s", pcnt->cont[index].sex);
		break;
	case 3:
		printf("请输入要修改的年龄:");
		scanf("%d", &pcnt->cont[index].age);
		break;
	case 4:
		printf("请输入要修改的电话:");
		scanf("%s", pcnt->cont[index].tele);
		break;
	case 5:
		printf("请输入要修改的地址:");
		scanf("%s", pcnt->cont[index].address);
		break;
	}
}
void SortContact(Contact *pcnt)//通讯录排序
{
	for (int i = 0; i < pcnt->size - 1; ++i)
	{
		for (int j  = 0; j < pcnt->size - i - 1; ++j)
		{
			if (strcmp(pcnt->cont[j].name, pcnt->cont[j + 1].name)>0)
			{
				PersonInfo tmp = pcnt->cont[j];
				pcnt->cont[j] = pcnt->cont[j + 1];
				pcnt->cont[j + 1] = tmp;
			}
		}
	}
	printf("排序成功!\n");
}

void ShowContact(Contact *pcnt)//打印通讯录
{
	printf("%-8s%-6s%-6s%-13s%s\n", "姓名", "性别", "年龄", "电话", "地址");
	for (int i = 0; i < pcnt->size; ++i)
	{
		printf("%-8s%-6s%-6d%-13s%s\n", pcnt->cont[i].name,
			pcnt->cont[i].sex,
			pcnt->cont[i].age,
			pcnt->cont[i].tele,
			pcnt->cont[i].address);
	}
}

4、源文件'ContactMain.c'

程序的主函数,实现目录的打印,以及自定义函数的调用,通过switch语句实现通讯录功能的选择。

#define _CRT_SECURE_NO_WARNINGS 1
#include"Contact.h"
int main(int argc,char* argv[])
{
	//初始化通讯录
	Contact cont;
	InitContact(&cont);
	int select = 1;
	while (select)
	{
		printf("******************************\n");
		printf("**********通 讯 录************\n");
		printf("*[1]Add            [2]Del    *\n");
		printf("*[3]Clear          [4]Find   *\n");
		printf("*[5]Modify         [6]Sort   *\n");
		printf("*[0]Exit           [7]Show   *\n");
		printf("******************************\n");
		printf("请选择:>");
		scanf("%d", &select);

		if (select == 0)
			break;
		switch (select)
		{
		case(Add):
			AddContact(&cont);
			break;
		case(Del) :
			DelContact(&cont);
			break;
		case(Clear) :
			ClearContact(&cont);
			break;
		case(Find) :
			FindContact(&cont);
			break;
		case(Modify) :
			ModifyContact(&cont);
			break;
		case(Sort) :
			SortContact(&cont);
			break;
		case(Show) :
			ShowContact(&cont);
			break;
		}
	}
	printf("退出通讯录系统…………\n");
	return 0;
}

评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

喜欢敲代码的大秃噜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值