资讯专栏INFORMATION COLUMN

通讯录小程序(C语言)

zorpan / 4532人阅读

摘要:通讯录主要由个功能增加联系人删除联系人修改联系人查找联系人按名称子排序。输入,退出通讯录。代码实现打印菜单创建一个通讯录初始化通讯录请选择退出通讯录。

程序介绍

通过前面学习我们可以实现通讯录小程序的代码,首先,我们需要创建一个通讯录,通讯录中存放1000个人的信息,信息包括:名字,性别,年龄,电话,住址。通讯录主要由5个功能:增加联系人、删除联系人、修改联系人、查找联系人、按名称子排序。下面我们来看实现过程。

实现思路和内容概括

首先我们将完整的代码分为3个部分——contact.h(头文件)、contact.c(函数部分)、test.c(主函数实现部分)。我们会创建一个大的框架,将菜单放入其中,菜单有7个选项:1.add 2.del 3.search 4.modify 5.show 6.sort 0.exit
输入“1”,添加联系人信息,输入“2”,删除指定联系人信息,输入“3”,查找指定联系人信息(按姓名查找并打印),输入“4”,修改指定联系人信息(按姓名查找),输入“5”,打印当前的通讯录所有联系人,输入“6”,将通讯录所有联系人按姓名排序。输入“0”,退出通讯录。

代码实现

打印菜单

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");	printf("****************************/n");}enum Option{	EXIT,	ADD,	DEL,	SEARCH,	MODIFY,	SHOW,	SORT};int main(){	int input=0;	//创建一个通讯录	struct Contact con;	//初始化通讯录	InitContact(&con);	do	{		menu();		printf("请选择:>");		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;		case SORT:			SortContactByName(&con);			break;		case EXIT:			printf("退出通讯录。/n");			break;		default:			printf("选择错误!/n");			break;		}	} while (input);	return 0;}

我们利用枚举类型将EXIT,ADD,DEL,SEARCH,MODIFY,SHOW,SORT放入其中,因为枚举类型中的成员属于常量所以具有常量的属性,我们可以利用此属性运用到switch上,这样就提高了代码的可读性。利用do while循环,我们先打印menu()函数,再利用input变量,只要输入非0,都会打印菜单,只是效果不同。

定义通讯录

//描述人的信息#define NAME_MAX 20#define SEX_MAX 5#define TELE_MAX 12#define ADDR_MAX 30#define MAX 1000struct PeoInfo{	char name[NAME_MAX];	int age;	char sex[SEX_MAX];	char tele[TELE_MAX];	char addr[ADDR_MAX];};//通讯录struct Contact{	struct PeoInfo data[MAX];//1000个人的信息存放进data数组中	int sz ;//记录当前存放进通讯录中的有效信息的个数};

定义一个通讯录需要两个结构体,struct PeoInfo结构体是描述一个人的信息,struct Contact结构体是通讯录本身,我们将struct PeoInfo中的个人信息存放在struct Contact结构体中以实现联系,也就是struct Contact的成员data[1000]是struct PeoInfo结构体类型,data[1000]是一个结构体类型的数组,里面有name[20],age,sex[5],tele[12],addr[30]。

初始化通讯录函数

void InitContact(struct Contact* pc){	pc->sz = 0;//默认没有信息	//memset(pc->data, 0, MAX * sizeof(struct PeoInfo));	memset(pc->data, 0, sizeof(pc->data));}

当我们定义一个通讯录结构体时,数值都是随机值,因此我们需要初始化,将通讯录所有的信息数据都变成“0”,这里使用了memset()函数,我们在内存函数博客中介绍了这个函数,不在细说。具体实现原理可以看前面的博客内存函数(C语言)

添加联系人函数

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++;	}}

AddContact()函数,首先先进行判断,sz(记录当前存放进通讯录中的有效信息的个数)是否等于MAX(1000),如果有,则打印通讯录已满,如果没有则按要求输入信息,并提示添加成功,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);	}}

在ShowContact()函数中,我们先打印标题"name", “age”, “sex”, “tele”, “addr”,然后利用for循环将信息一一对应标题都打印下来。

查找通讯录函数

int FindContactByName(const struct Contact* pc, const char *name){	int i = 0;	for (i = 0; i < pc->sz; i++)	{		if (strcmp(pc->data[i].name, name) == 0)		{			return i;		}	}	//找不到	return -1;}

FindContactByName()函数的基本实现是通过strcmp()函数实现的,利用for循环,找到查找的名字于通讯录名字相等的此时i的值,并返回i的值,此时i的值正是data数组的下标,方便后续操作,关于strcmp()函数实现原理可以看以前博客字符与字符串函数(C语言)。

删除联系人

void DelContact(struct Contact* pc){	if (pc->sz == 0)	{		printf("通讯录为空,无法删除/n");		return;	}	char name[NAME_MAX] = { 0 };	printf("请输入要删除人的名字:>");	scanf("%s", name);	//查找	int pos = FindContactByName(pc, name);	if (pos == -1)	{		printf("指定的联系人不存在/n");	}	else	{		//删除		int j = 0;		for (j = pos; j < pc->sz-1; j++)		{			pc->data[j] = pc->data[j + 1];		}		pc->sz--;		//提示		printf("删除成功/n");	}}

DelContact()函数和AddContact()函数类似,但是比添加联系人要复杂,删除联系人先再找到指定的联系人,在进行操作,因此,DelContact()函数中运用了查找通讯录函数,利用名字进行比较找出指定的联系人,在进行删除时,并不是直接删除,而是利用后一个信息将前一个信息的覆盖,如此达到删除联系人的信息。

查找指定联系人

void SearchContact(const struct Contact* pc){	char name[NAME_MAX] = { 0 };	printf("输入要查找人的名字:>");	scanf("%s", name);	int pos = FindContactByName(pc, name);	if (-1 == pos)	{		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);	}}

SearchContact()函数是在FindContactByName()函数的基础之上增加了打印的功能,如果没有查找到指定的联系人打印“查无此人”,否则打印出该联系人的所有信息。

修改指定联系人信息

void ModifyContact(struct Contact* pc){	char name[NAME_MAX] = { 0 };	printf("输入要修改人的名字:>");	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);	}}

ModifyContact()函数是利用FindContactByName()函数先将想要修改的联系人找到,然后输入新的所有信息来覆盖原来的信息。

排序(按姓名)

int cmp_name(const void* e1, const void* e2){	return strcmp(((struct Contact*)e1)->data->name , ((struct Contact*)e2)->data->name);}void SortContactByName(struct Contact* pc){	qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_name);	printf("排序成功/n");}

排序运用到了qsort()函数,这个函数可以排序任意类型的数据,因此结构体也可以。但是需要引用到头文件#include
qsort()函数:
形式:void qsort( void *base, size_t num, size_t width, int (__cdecl *compare )(const void *elem1, const void *elem2 ) )
解释:qsort函数实现了一种快速排序算法,用于对num元素数组进行排序,每个元素的宽度为字节。参数base是指向要排序的数组的基的指针。qsort用已排序的元素覆盖此数组。参数compare是指向用户提供的例程的指针,该例程比较两个数组元素并返回指定其关系的值。
也就是说,*base是一个指针,num是要排序的个数,width是排序元素的大小,int (__cdecl *compare )(const void *elem1, const void *elem2 ) 是一个函数,这个函数就是用来判断怎样比较的。以写的代码为例,pc是指针指向的是struct Contact con结构体,pc->sz是记录当前存放进通讯录中的有效信息的个数,也就对应了打印的个数,sizeof(pc->data[0])是个人信息的结构体的大小,cmp_name()函数是按名字来进行排序。

完整代码

contact.h

#include#include #include#define NAME_MAX 20#define SEX_MAX 5#define TELE_MAX 12#define ADDR_MAX 30#define MAX 1000//描述人的信息struct PeoInfo{	char name[NAME_MAX];	int age;	char sex[SEX_MAX];	char tele[TELE_MAX];	char addr[ADDR_MAX];};//通讯录struct Contact{	struct PeoInfo data[MAX];//1000个人的信息存放进data数组中	int sz ;//记录当前存放进通讯录中的有效信息的个数};//初始化通讯录void InitContact(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);//按姓名排序通讯录void SortContactByName(struct Contact* pc);

用#define定义的常量能够方便代码的修改,增加了代码的维护性。

contact.c

#include"contact.h"void InitContact(struct Contact* pc){	pc->sz = 0;//默认没有信息	//memset(pc->data, 0, MAX * sizeof(struct PeoInfo));	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, const char *name){	int i = 0;	for (i = 0; i < pc->sz; i++)	{		if 
                 
               
              

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/121134.html

相关文章

  • 我是如何自学C语言的(一个菜鸟的学习路)

    摘要:还有书,入门的书我买了好几本,到最后真正看的只有一本,就是谭浩强的那本。当然也不排除特别差的教程,我当初的入门教程是小甲鱼的,叫做带你学带你飞,书是谭浩强的语言程序设计第四版。 首先,本人也是一个菜鸟,目前依然还在学习,当初在我开始自学C语言的时候,走过了好多弯路,如果你看到这篇文章,希望你不要走我走过的弯路,这也是我写这篇文章的目的,我也不想像老头子一样叨叨叨,哪些要做,哪些不要做,...

    newtrek 评论0 收藏0
  • 微信程序初体验,入门练手项目--讯录,后台是阿里云服务器

    摘要:最近微信小程序异常火爆,很多人在学习,下面带着大家搭建下微信小程序的调试环境,并调试入门练手项目通讯录和基础即可微信推荐使用的语言,去菜鸟教程简单学习下,,,即可,方便大家学习。 一、前言(坑爹的玩意) 项目源码:https://github.com/saucxs/wx_... 微信小程序自从2017年,被各种看好,不过一段时间过去了还是反响平平,下半年随着各项功能的开放,很多企业...

    kel 评论0 收藏0

发表评论

0条评论

zorpan

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<