【C语言实战项目】通讯录

一.了解项目功能

在本次实战项目中我们的目标是实现一个通讯录:

该通讯录可以用来存储1000个人的信息

每个人的信息包括:姓名年龄性别住址电话

通讯录提供功能有:

  1. 添加联系人信息
  2. 删除指定联系人信息
  3. 查找指定联系人信息
  4. 修改指定联系人信息
  5. 显示所有联系人信息
  6. 清空所有联系人
  7. 用四种排序方式对所有联系人进行排序

 二.项目功能演示

要编写一个通讯录项目,首先要明确我们想要达到的效果是什么样,下面我将用vs2022编译器来为大家演示一下通讯录运行时的样子:

首先,我们来到菜单界面,提醒用户选择通讯录中的某一功能:


 当用户选择'0'时,退出程序


 当用户选择'1'时,依次提醒用户输入增添的联系人信息,包括名字,年龄,性别,地址,电话.

输入完毕后提示用户联系人添加成功:


 当用户输入'2'时,提示用户输入要删除的人的名字,当用户输入后,提示删除成功:

 当没有找到要删除的对象时,提示用户没有找到要删除的对象:

 


用户输入'3'时, 提示用户输入要查找的联系人姓名,并在找到后打印出该联系人的信息:

如果没有找到,则提示用户没有找到该联系人:

 


用户输入'4'时,提示用户输入要修改的人的名字,并在之后提示用户依次输入修改后的该联系人信息,录入完成后,提示修改成功并再次打印修改后的该联系人信息.

 当用户输入联系人不存在时,提示用户没有找到要修改的对象:


 当用户选择'5'时,打印当前通讯录中所有联系人的信息:


用户选择'7'时, 提示用户选择排序方式.

选择1时,则将通讯录按姓名排序并打印排序结果:

 当选择2时,则将通讯录按年龄排序并打印排序结果:

 当选择3时,则将通讯录按性别排序并打印排序结果:

 当选择4时,则将通讯录按住址排序并打印排序结果:


用户选择'6'时,清空通讯录中的所有联系人信息:

当通讯录原本为空时,提示用户无需清空:


 以上就是通讯录的功能演示,下面我们则需要分12步,逐步实现上面演示的所有功能.


三.逐步实现项目功能及其逻辑详解

通过第二部分对项目功能的介绍,我们已经对通讯录的功能有了大致的了解,虽然看似需要实现的功能很多,貌似一时间不知该如何下手,但我们可以分步分模块来分析这个项目的流程,最后再将各各部分进行整合,所以大家不用担心,跟着我一步一步分析吧!


!!!注意,该部分的代码只是为了详细介绍某一部分的项目实现逻辑,故可能会删减一些与该部分不相关的代码以便大家理解,需要查看完整详细代码可以移步本文第四部分。


1.实现通讯录菜单

菜单部分的逻辑比较简单,就是利用C语言printf函数打印出这个菜单界面即可。基础问题就不过多赘述了,代码如下:

void menu()
{
	printf("******************************************\n");
	printf("******************************************\n");
	printf("*******      1.add      2.del      *******\n");
	printf("*******      3.search   4.modify   *******\n");
	printf("*******      5.show     6.empty    *******\n");
	printf("*******      7.sort     0.exit     *******\n");
	printf("******************************************\n");
	printf("******************************************\n");
}

2.实现通讯录程序功能可循环使用

由于我们要实现通讯录功能可以反复使用的逻辑,因此选择do...while的循环语句来实现这一部分的逻辑,该部分每步的详细解释见代码注释:

void menu()//菜单函数实现打印菜单
{
	printf("******************************************\n");
	printf("******************************************\n");
	printf("*******      1.add      2.del      *******\n");
	printf("*******      3.search   4.modify   *******\n");
	printf("*******      5.show     6.empty    *******\n");
	printf("*******      7.sort     0.exit     *******\n");
	printf("******************************************\n");
	printf("******************************************\n");
}

int main()
{
	int input = 0;

	Contact con;//创建通讯录
	
	InitContact(&con);//初始化通讯录

	do//使用do  while语句来实现通讯录功能可以反复使用
	{
		menu();//菜单函数,打印菜单提示用户选择

		printf("请选择:>");//提醒用户选择

		scanf("%d", &input);//用scanf接收用户选择存入变量input中

		switch (input)//利用分支语句实现用户的选择
		{
			case 1://当用户选择'1',增添联系人
				AddContact(&con);
				break;

			case 2://当用户选择'2',删除联系人
				DelContact(&con);
				break;

			case 3://当用户选择'3',查找联系人
				searchContact(&con);
				break;

			case 4://当用户选择'4',修改联系人
				modifyContact(&con);
				break;

			case 5://当用户选择'5',打印联系人
				ShowContact(&con);
				break;

			case 6://当用户选择'6',清空联系人
				EmptyContact(&con);
				break;

			case 7://当用户选择'7',排序联系人
				SortContact(&con);
				break;

			case 0://当用户输入0,提醒用户退出程序
				printf("退出程序:>\n");
				break;

			default://当用户输入了非选项数字时,提醒用户重新输入
				printf("输入非法,请重新输入!\n");
				break;
		}
	} while (input);//用变量input的值作为while循环的判定执行条件
	                    //当input不为0时,该循环都可一直运行下去。

	return 0;
}

3.创建通讯录

创建通讯录成员的结构体应包括:姓名,年龄,性别,地址和电话这5个信息.

因此我们创建PeoInfo结构体类型时应由四个字符数组以及一个整形来组成.

同时我们需要一个整形来记录目前该通讯录中已存入的联系人个数.

因此我们创建Contact结构体类型时应由一个整形sz及一个结构体数组data组成.

而使用宏定义可以方便我们后续对各个结构的大小做调整.

综上,该部分代码如下:

#define MAX 1000
#define NAME_MAX 20
#define SEX_MAX 6
#define ADDR_MAX 30
#define TELE_MAX 12

//人的信息-结构体
typedef struct PeoInfo
{
	char name[NAME_MAX];
	int age;
	char sex[SEX_MAX];
	char addr[ADDR_MAX];
	char tele[TELE_MAX];//电话11位,留一位给'\0';
}PeoInfo;

typedef struct Contact
{
	PeoInfo data[MAX];//存放1000个人的信息
	int sz;//用来记录当前已经存放的信息的个数
}Contact;

 4.初始化通讯录

初始化通讯录的逻辑非常简单,我们使用memset()函数完成对date结构体数组的空间初始化即可.

该部分代码如下:

//初始化通讯录成员
void InitContact(Contact* pc)
{
	assert(pc);

	pc->sz = 0;
	memset(pc->data, 0, sizeof(pc->data));
}

 5.添加联系人信息

要添加联系人信息,首先需要判断当前通讯录是否还能添加,即判断联系人是否已经满了.

其次只需要逐一接收用户输入的信息存入对应结构体中即可:

该部分代码如下:

void AddContact(Contact* pc)
{
	assert(pc);

	//防止通讯录满了
	if (pc->sz == MAX)
	{
		printf("通讯录已满,无法添加\n");
		return;
	}
	//录入增加的一个人的信息
	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].addr);

	printf("请输入电话;>");
	scanf("%s", pc->data[pc->sz].tele);

	//每次录入完,sz自增
	pc->sz++;
	printf("联系人添加成功:>\n");
}

 6.按任人名查找指定联系人

因为后续删除,查找,修改等功能都是以输入姓名然后查找到对应联系人后进行操作的,

所以我们提前编写好一个用于人名查询的被调函数,

该被调函数的功能为:接收主调函数传入的人名信息,并在通讯录中查找,

如果找到了返回该联系人在通讯录中的序号,如果没有找到返回-1.

代码如下:

int FindByName(const Contact* pc, char* name)
{
	assert(pc);

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

7.删除指定联系人信息

要删除首先要判断当前通讯录联系人个数是否为0,为0则无法再进行删除操作.

其次提示用户输入要删除的联系人姓名,交给FindByName()函数查找,

如果找到了,则从该位置依次前移联系人,从而达到删除联系人的效果,图示如下:

 如果没有找到用户输入的联系人信息则不执行,代码如下:

void DelContact(Contact* pc)
{
	assert(pc);

	char name[NAME_MAX] = { 0 };
	//防止通讯录删完了
	if (pc->sz == 0)
	{
		printf("通讯录为空,无法删除\n");
		return;
	}

	//找到要删除的对象
	printf("请输入要删除的人的名字:>");
	scanf("%s", name);
	int del=FindByName(pc,name);

	
	if (-1== del)
	{
		printf("抱歉,没有找到您要删除的对象;<\n");
		return;
	}
	int i = 0;
	//删除
	for (i = del; i < pc->sz-1; i++)
	{
		pc->data[i] = pc->data[i + 1];
	}
	pc->sz--;
	printf("删除成功;>\n");
}

8.查找联系人信息并打印

该部分实现较为简单,只需要借助FindByName函数找到联系人位置并打印其信息即可,

代码如下:

void searchContact(const Contact* pc)
{
	assert(pc);
	char name[NAME_MAX] = { 0 };
	//找到要查找的对象
	printf("请输入要查找的人的名字:>");
	scanf("%s", name);
	int sea = FindByName(pc, name);

	if (-1 == sea)
	{
		printf("抱歉,没有找到您要查找的对象;<\n");
		return;
	}

	//打印信息
	printf("________________________________________________________________________________________\n");
	printf("%-4s\t%-20s\t%-4s\t%-6s\t%-20s\t%-12s\n", "|序号", "|姓名", "|年龄", "|性别", "|地址", "|电话");
	printf("________________________________________________________________________________________\n");
	printf("|%-4d\t|%-20s\t|%-4d\t|%-6s\t|%-20s\t|%-12s\n",sea+1,
			pc->data[sea].name,
			pc->data[sea].age,
			pc->data[sea].sex,
			pc->data[sea].addr,
			pc->data[sea].tele);
	printf("________________________________________________________________________________________\n");
}

 9.修改指定联系人信息

该部分功能实现较为简单,只需要借助FindByName函数找到联系人位置并在重新录入其信息后打印修改后的信息即可,

代码如下:

void modifyContact(Contact* pc)
{
	assert(pc);

	char name[NAME_MAX] = { 0 };
	//找到要修改的对象
	printf("请输入要修改的人的名字:>");
	scanf("%s", name);
	int mod = FindByName(pc, name);

	if (-1 == mod)
	{
		printf("抱歉,没有找到您要修改的对象;<\n");
		return;
	}
	printf("请输入修改后的联系人信息\n");
	printf("请输入名字;>");
	scanf("%s", pc->data[mod].name);

	printf("请输入年龄;>");
	scanf("%d", &(pc->data[mod].age));

	printf("请输入性别;>");
	scanf("%s", pc->data[mod].sex);

	printf("请输入地址;>");
	scanf("%s", pc->data[mod].addr);

	printf("请输入电话;>");
	scanf("%s", pc->data[mod].tele);

	printf("修改成功;>\n");

	printf("________________________________________________________________________________________\n");
	printf("%-4s\t%-20s\t%-4s\t%-6s\t%-20s\t%-12s\n", "|序号", "|姓名", "|年龄", "|性别", "|地址", "|电话");
	printf("________________________________________________________________________________________\n");
	printf("|%-4d\t|%-20s\t|%-4d\t|%-6s\t|%-20s\t|%-12s\n", mod + 1,
		pc->data[mod].name,
		pc->data[mod].age,
		pc->data[mod].sex,
		pc->data[mod].addr,
		pc->data[mod].tele);
	printf("________________________________________________________________________________________\n");
}

 10.显示所有联系人信息

该部分只需要借助循环结构将通讯录中所有成员打印即可,但需要使用大量格式控制符来确保打印的通讯录整洁,美观.

代码如下:

void ShowContact(const Contact* pc)
{ 
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空,无法显示\n");
		return;
	}
	int i = 0;
	printf("________________________________________________________________________________________\n");
	printf("%-4s\t%-20s\t%-4s\t%-6s\t%-20s\t%-12s\n", "|序号","|姓名", "|年龄", "|性别", "|地址", "|电话");
	for (i = 0; i < pc->sz; i++)
	{
		printf("________________________________________________________________________________________\n");
		printf("|%-4d\t|%-20s\t|%-4d\t|%-6s\t|%-20s\t|%-12s\n",i+1,
																pc->data[i].name,
																pc->data[i].age,
																pc->data[i].sex,
																pc->data[i].addr,
																pc->data[i].tele);
		
	}
	printf("________________________________________________________________________________________\n");

}

 11.清空所有联系人

清空所有联系人的逻辑与最开始的初始化通讯录的逻辑相同,借助memset()函数完成即可,

但在清空前需要判断当前通讯录是否为空,如果为空则不需要进行清空操作,

代码如下:

void EmptyContact(Contact* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空,无需清空\n");
		return;
	}
	pc->sz = 0;
	memset(pc->data, 0, sizeof(pc->data));
	printf("清空成功:>\n");

}

 12.用四种排序方式给所有联系人排序

该部分分为两个模块:

  1. 排序逻辑的实现
  2. 借助qsort函数排序,需要完成排序函数comper的编写.

在实现第一模块时,尤其要注意使用qsort()函数时参数的传递,如果有对qsort()函数还不了解的朋友可以移步我的这篇博客:qsort()函数详解:能给万物排序的神奇函数

里面有0基础的qsort()函数(快速排序函数)的详解,应该可以帮助你完全掌握该函数.

下面是第一模块的代码:

//给联系人排序
void SortContact(Contact* pc)
{
	int cho = 0;
	if (pc->sz == 0)
	{
		printf("通讯录为空,请先加入联系人\n");
		return;
	}
	printf("******************************\n");
	printf("********   1.按姓名  *********\n");
	printf("********   2.按年龄  *********\n");
	printf("********   3.按性别  *********\n");
	printf("********   4.按地址  *********\n");
	printf("******************************\n");
	printf("请选择您想使用的排序方式:>");
	scanf("%d", &cho);

	int (*compare_func)(const void*, const void*) = NULL;

	switch (cho)
	{
	case 1:
		compare_func = comper_name;
		break;
	case 2:
		compare_func = comper_age;
		break;
	case 3:
		compare_func = comper_sex;
		break;
	case 4:
		compare_func = comper_addr;
		break;
	default:
		printf("排序选项无效:<\n");
		return;
	}

	// 使用qsort函数进行排序
	qsort(pc->data, pc->sz, sizeof(PeoInfo), compare_func);

	printf("排序成功:>\n");

	ShowContact(pc);
}

下面是第二模块的代码:

//comper按姓名排序
int comper_name(const void* a, const void* b)
{
	const PeoInfo* personA = (const PeoInfo*)a;
	const PeoInfo* personB = (const PeoInfo*)b;
	return strcmp(personA->name, personB->name);
}
//comper按年龄排序
int comper_age(const void* a, const void* b)
{
	const PeoInfo* personA = (const PeoInfo*)a;
	const PeoInfo* personB = (const PeoInfo*)b;
	return (personA->age-personB->age);
}
//comper按性别排序
int comper_sex(const void* a, const void* b) 
{
	const PeoInfo* personA = (const PeoInfo*)a;
	const PeoInfo* personB = (const PeoInfo*)b;
	return strcmp(personA->sex, personB->sex);
}
//comper按住处排序
int comper_addr(const void* a, const void* b) 
{
	const PeoInfo* personA = (const PeoInfo*)a;
	const PeoInfo* personB = (const PeoInfo*)b;
	return strcmp(personA->addr, personB->addr);
}

 四.整合代码并测试运行

我们将程序运行的代码分为三个模块分开书写,完整代码如下:

contact.c

//contact.c通讯录的实现
#include"contact.h"


//初始化通讯录成员
void InitContact(Contact* pc)
{
	assert(pc);

	pc->sz = 0;
	memset(pc->data, 0, sizeof(pc->data));
}


//增加通讯录中的联系人
void AddContact(Contact* pc)
{
	assert(pc);

	//防止通讯录满了
	if (pc->sz == MAX)
	{
		printf("通讯录已满,无法添加\n");
		return;
	}
	//录入增加的一个人的信息
	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].addr);

	printf("请输入电话;>");
	scanf("%s", pc->data[pc->sz].tele);

	//每次录入完,sz自增
	pc->sz++;
	printf("联系人添加成功:>\n");
}


//按人名查找联系人
int FindByName(const Contact* pc, char* name)
{
	assert(pc);

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


//删除通讯录中的成员
void DelContact(Contact* pc)
{
	assert(pc);

	char name[NAME_MAX] = { 0 };
	//防止通讯录删完了
	if (pc->sz == 0)
	{
		printf("通讯录为空,无法删除\n");
		return;
	}

	//找到要删除的对象
	printf("请输入要删除的人的名字:>");
	scanf("%s", name);
	int del=FindByName(pc,name);

	
	if (-1== del)
	{
		printf("抱歉,没有找到您要删除的对象;<\n");
		return;
	}
	int i = 0;
	//删除
	for (i = del; i < pc->sz-1; i++)
	{
		pc->data[i] = pc->data[i + 1];
	}
	pc->sz--;
	printf("删除成功;>\n");
}


//查找联系人信息并打印
void searchContact(const Contact* pc)
{
	assert(pc);
	char name[NAME_MAX] = { 0 };
	//找到要查找的对象
	printf("请输入要查找的人的名字:>");
	scanf("%s", name);
	int sea = FindByName(pc, name);

	if (-1 == sea)
	{
		printf("抱歉,没有找到您要查找的对象;<\n");
		return;
	}

	//打印信息
	printf("________________________________________________________________________________________\n");
	printf("%-4s\t%-20s\t%-4s\t%-6s\t%-20s\t%-12s\n", "|序号", "|姓名", "|年龄", "|性别", "|地址", "|电话");
	printf("________________________________________________________________________________________\n");
	printf("|%-4d\t|%-20s\t|%-4d\t|%-6s\t|%-20s\t|%-12s\n",sea+1,
			pc->data[sea].name,
			pc->data[sea].age,
			pc->data[sea].sex,
			pc->data[sea].addr,
			pc->data[sea].tele);
	printf("________________________________________________________________________________________\n");
}


//修改联系人信息
void modifyContact(Contact* pc)
{
	assert(pc);

	char name[NAME_MAX] = { 0 };
	//找到要修改的对象
	printf("请输入要修改的人的名字:>");
	scanf("%s", name);
	int mod = FindByName(pc, name);

	if (-1 == mod)
	{
		printf("抱歉,没有找到您要修改的对象;<\n");
		return;
	}
	printf("请输入修改后的联系人信息\n");
	printf("请输入名字;>");
	scanf("%s", pc->data[mod].name);

	printf("请输入年龄;>");
	scanf("%d", &(pc->data[mod].age));

	printf("请输入性别;>");
	scanf("%s", pc->data[mod].sex);

	printf("请输入地址;>");
	scanf("%s", pc->data[mod].addr);

	printf("请输入电话;>");
	scanf("%s", pc->data[mod].tele);

	printf("修改成功;>\n");

	printf("________________________________________________________________________________________\n");
	printf("%-4s\t%-20s\t%-4s\t%-6s\t%-20s\t%-12s\n", "|序号", "|姓名", "|年龄", "|性别", "|地址", "|电话");
	printf("________________________________________________________________________________________\n");
	printf("|%-4d\t|%-20s\t|%-4d\t|%-6s\t|%-20s\t|%-12s\n", mod + 1,
		pc->data[mod].name,
		pc->data[mod].age,
		pc->data[mod].sex,
		pc->data[mod].addr,
		pc->data[mod].tele);
	printf("________________________________________________________________________________________\n");
}


//显示通讯录中的信息
void ShowContact(const Contact* pc)
{ 
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空,无法显示\n");
		return;
	}
	int i = 0;
	printf("________________________________________________________________________________________\n");
	printf("%-4s\t%-20s\t%-4s\t%-6s\t%-20s\t%-12s\n", "|序号","|姓名", "|年龄", "|性别", "|地址", "|电话");
	for (i = 0; i < pc->sz; i++)
	{
		printf("________________________________________________________________________________________\n");
		printf("|%-4d\t|%-20s\t|%-4d\t|%-6s\t|%-20s\t|%-12s\n",i+1,
																pc->data[i].name,
																pc->data[i].age,
																pc->data[i].sex,
																pc->data[i].addr,
																pc->data[i].tele);
		
	}
	printf("________________________________________________________________________________________\n");

}


//清空联系人信息
void EmptyContact(Contact* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空,无需清空\n");
		return;
	}
	pc->sz = 0;
	memset(pc->data, 0, sizeof(pc->data));
	printf("清空成功:>\n");

}


//comper按姓名排序
int comper_name(const void* a, const void* b)
{
	const PeoInfo* personA = (const PeoInfo*)a;
	const PeoInfo* personB = (const PeoInfo*)b;
	return strcmp(personA->name, personB->name);
}
//comper按年龄排序
int comper_age(const void* a, const void* b)
{
	const PeoInfo* personA = (const PeoInfo*)a;
	const PeoInfo* personB = (const PeoInfo*)b;
	return (personA->age-personB->age);
}
//comper按性别排序
int comper_sex(const void* a, const void* b) 
{
	const PeoInfo* personA = (const PeoInfo*)a;
	const PeoInfo* personB = (const PeoInfo*)b;
	return strcmp(personA->sex, personB->sex);
}
//comper按住处排序
int comper_addr(const void* a, const void* b) 
{
	const PeoInfo* personA = (const PeoInfo*)a;
	const PeoInfo* personB = (const PeoInfo*)b;
	return strcmp(personA->addr, personB->addr);
}


//给联系人排序
void SortContact(Contact* pc)
{
	int cho = 0;
	if (pc->sz == 0)
	{
		printf("通讯录为空,请先加入联系人\n");
		return;
	}
	printf("******************************\n");
	printf("********   1.按姓名  *********\n");
	printf("********   2.按年龄  *********\n");
	printf("********   3.按性别  *********\n");
	printf("********   4.按地址  *********\n");
	printf("******************************\n");
	printf("请选择您想使用的排序方式:>");
	scanf("%d", &cho);

	int (*compare_func)(const void*, const void*) = NULL;

	switch (cho)
	{
	case 1:
		compare_func = comper_name;
		break;
	case 2:
		compare_func = comper_age;
		break;
	case 3:
		compare_func = comper_sex;
		break;
	case 4:
		compare_func = comper_addr;
		break;
	default:
		printf("排序选项无效:<\n");
		return;
	}

	// 使用qsort函数进行排序
	qsort(pc->data, pc->sz, sizeof(PeoInfo), compare_func);

	printf("排序成功:>\n");

	ShowContact(pc);
}

contact.h

#pragma once
//contact.h函数的声明
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>

#define MAX 1000
#define NAME_MAX 20
#define SEX_MAX 6
#define ADDR_MAX 30
#define TELE_MAX 12

//人的信息-结构体
typedef struct PeoInfo
{
	char name[NAME_MAX];
	int age;
	char sex[SEX_MAX];
	char addr[ADDR_MAX];
	char tele[TELE_MAX];//电话11位,留一位给'\0';
}PeoInfo;

typedef struct Contact
{
	PeoInfo data[MAX];//存放1000个人的信息
	int sz;//用来记录当前已经存放的信息的个数
}Contact;

//初始化通讯录
void InitContact(Contact* pc);

//增加联系人
void AddContact(Contact* pc);

//删除通讯录中的信息
void DelContact(Contact* pc);

//显示通讯录中的信息
void ShowContact(const Contact* pc);

//查找联系人并打印其信息
void searchContact(const Contact* pc);

//修改联系人信息
void modifyContact(Contact* pc);

//清空联系人信息(和初始化逻辑一模一样)
void EmptyContact(Contact* pc);

//给联系人排序
void SortContact(Contact* pc);

test.c

//bit.c测试通讯录

#include"contact.h"

void menu()
{
	printf("******************************************\n");
	printf("******************************************\n");
	printf("*******      1.add      2.del      *******\n");
	printf("*******      3.search   4.modify   *******\n");
	printf("*******      5.show     6.empty    *******\n");
	printf("*******      7.sort     0.exit     *******\n");
	printf("******************************************\n");
	printf("******************************************\n");
}

int main()
{
	int input = 0;
	//创建通讯录
	Contact con;
	//初始化通讯录

	InitContact(&con);
	do
	{
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
			case 1:
				AddContact(&con);
				break;
			case 2:
				DelContact(&con);
				break;
			case 3:
				searchContact(&con);
				break;
			case 4:
				modifyContact(&con);
				break;
			case 5:
				ShowContact(&con);
				break;
			case 6:
				EmptyContact(&con);
				break;
			case 7:
				SortContact(&con);
				break;
			case 0:
				printf("退出程序:>\n");
				break;
			default:
				printf("输入非法,请重新输入!\n");
				break;
		}
	} while (input);
	
	return 0;
}

测试运行部分则在开篇项目功能演示部分就已经测试运行过了,有兴趣的朋友可以将代码拷贝在自己的编译器中运行完善,篇幅有限,我就不多赘述了.

有什么问题,欢迎大家留言和我一起讨论.

感谢您的支持,这是我创作的最大动力.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/74461.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python中两个数据框之间的遍历

1.输入文件1 文件1&#xff1a;第一列是基因名字&#xff0c;列2&#xff1a;外显子起始位置&#xff0c;列3&#xff1a;外显子终止位置&#xff0c;列4&#xff1a;外显子的序号 2.输入文件2&#xff1a; 备注&#xff1a;列1&#xff1a;基因id&#xff1b;列2&#xff1a;…

Verdi_如何dump信号的驱动强度

Verdi_如何dump信号的驱动强度 需求背景 在Verilog语法标准中&#xff0c;0和1各自被分成了8个强度等级&#xff1b; Strength NameStrength NameStrength Levelsupply 0supply 17strong 0strong 16pull 0pull 15large 0large 14weak 0weak 13medium 0medium 12small 0small…

软件测试用例设计方法之因果图法

基本概念 因果图是一种利用图解法分析输入的各种组合情况&#xff0c;从而设计测试用例的方法&#xff0c;它适合于检查程序输入条件的各种组合情况。 设计测试用例的步骤 分析软件规格说明描述中, 哪些是原因(即输入条件或输入条件的等价类),哪些是结果(即输出条件), 并给每…

『C语言初阶』第九章 -结构体

前言 今天小羊又来给铁汁们分享关于C语言的结构体&#xff0c;在C语言中&#xff0c;结构体类型属于一种构造类型&#xff08;其他的构造类型还有&#xff1a;数组类型&#xff0c;联合类型&#xff09;&#xff0c;今天我们主要简单了解一下结构体。 一、结构体是什么&#x…

Redis_缓存1_缓存类型

14.redis缓存 14.1简介 穿透型缓存&#xff1a; 缓存与后端数据交互在一起&#xff0c;对服务端的调用隐藏细节。如果从缓存中可以读到数据&#xff0c;就直接返回&#xff0c;如果读不到&#xff0c;就到数据库中去读取&#xff0c;从数据库中读到数据&#xff0c;也是先更…

基于微服务+Java+Spring Cloud +Vue+UniApp +MySql实现的智慧工地云平台源码

基于微服务JavaSpring Cloud VueUniApp MySql开发的智慧工地云平台源码 智慧工地概念&#xff1a; 智慧工地就是互联网建筑工地&#xff0c;是将互联网的理念和技术引入建筑工地&#xff0c;然后以物联网、移动互联网技术为基础&#xff0c;充分应用BIM、大数据、人工智能、移…

node.js+Vue+Express学生宿舍校舍系统-ggr80

关键词&#xff1a;智慧学生校舍&#xff1b;简洁方便直观&#xff1b; 本次的毕业设计主要就是设计并开发一个智慧学生校舍系统。使用数据库mysql。系统主要包括个人中心、学生管理、教师管理、宿管管理、外来人员管理、维修人员管理、学生信息管理、学生签到管理、学生物品管…

因果推断(四)断点回归(RD)

因果推断&#xff08;四&#xff09;断点回归&#xff08;RD&#xff09; 在传统的因果推断方法中&#xff0c;有一种方法可以控制观察到的混杂因素和未观察到的混杂因素&#xff0c;这就是断点回归&#xff0c;因为它只需要观察干预两侧的数据&#xff0c;是否存在明显的断点…

利用ChatGPT绘制思维导图——以新能源汽车竞品分析报告为例

随着人们对环境保护的日益关注和传统燃油汽车的限制&#xff0c;全球范围内对新能源汽车的需求不断增长。新能源汽车市场的激烈竞争使得了解各个竞品的特点和优劣成为关键。然而&#xff0c;针对这一领域的详尽竞品分析却常常需要大量时间和精力。 在此背景下&#xff0c;人工智…

音视频 vs2017配置FFmpeg

vs2017 ffmpeg4.2.1 一、首先我把FFmpeg整理了一下&#xff0c;放在C盘 二、新建空项目 三、添加main.cpp&#xff0c;将bin文件夹下dll文件拷贝到cpp目录下 #include<stdio.h> #include<iostream>extern "C" { #include "libavcodec/avcodec.h&…

【计算机网络】Udp详解

前言 上几文章我们讲解了应用层协议Http和Https&#xff0c;要知道应用层协议有很多&#xff0c;这些都是程序员自己定制的&#xff0c;而真正要传输的时候&#xff0c;是要在操作系统的传输层进行的&#xff0c;今天我们就来学习一下传输层协议Udp的 标识一个通信 要进行跨…

OSI七层模型和TCP/IP四层模型

OSI七层模型和TCP/IP四层模型 七层模型(OSI) OSI七层模型&#xff08;Open Systems Interconnection Reference Model&#xff09;是一个用于计算机网络体系结构的标准化框架&#xff0c;旨在定义网络通信中不同层次的功能和协议。 各个层次具体如下&#xff1a; 物理层&am…

MongoDB的下载和安装

一、MongoDB下载 下载地址&#xff1a;https://www.mongodb.com/try/download/community 二、安装 因为选择下载的是 .zip 文件&#xff0c;直接跳过安装&#xff0c;一步到位。 选择在任一磁盘创建空文件夹&#xff08;不要使用中文路径&#xff09;&#xff0c;解压之后把…

DaVinci Resolve Studio 18 for Mac 达芬奇调色

DaVinci Resolve Studio 18是一款专业的视频编辑和调色软件&#xff0c;适用于电影、电视节目、广告等各种视觉媒体的制作。它具有完整的后期制作功能&#xff0c;包括剪辑、调色、特效、音频处理等。 以下是DaVinci Resolve Studio 18的主要特点&#xff1a; - 提供了全面的视…

nginx一般轮询、加权轮询、ip_hash等负载均衡模式配置介绍

一.负载均衡含义简介 二.nginx负载均衡配置方式 准备三台设备&#xff1a; 2.190均衡服务器&#xff0c;2.191web服务器1&#xff0c;2.160web服务器2&#xff0c;三台设备均安装nginx&#xff0c;两台web服务器均有网页内容 1.一般轮询负载均衡 &#xff08;1&#xff09…

马来西亚的区块链和NFT市场调研

马来西亚的区块链和NFT市场调研 基本介绍 参考&#xff1a; https://zh.wikipedia.org/wiki/%E9%A9%AC%E6%9D%A5%E8%A5%BF%E4%BA%9A zz制度&#xff1a;联邦议会制 语言文字&#xff1a; 马来语 民族&#xff1a; 69.4%原住民&#xff08;土著&#xff09;&#xff0c;23.2%…

逗号操作符

逗号表达式&#xff0c;就是用逗号隔开的多个表达式。 逗号表达式&#xff0c;从左向右依次执行。整个表达式的结果是最后一个表达式的结果。 运用&#xff1a;

人工智能任务1-【NLP系列】句子嵌入的应用与多模型实现方式

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能任务1-【NLP系列】句子嵌入的应用与多模型实现方式。句子嵌入是将句子映射到一个固定维度的向量表示形式&#xff0c;它在自然语言处理&#xff08;NLP&#xff09;中有着广泛的应用。通过将句子转化为向量…

(七)Unity VR项目升级至Vision Pro需要做的工作

Vision Pro 概述 定位为混合现实眼镜&#xff0c;对AR支持更友好 无手柄&#xff0c;支持手&#xff08;手势&#xff09;、眼&#xff08;注视&#xff09;、语音交互 支持空间音频&#xff0c;相比立体声、环绕声更有沉浸感和空间感 支持VR/AR应用&#xff0c;支持多种应用模…

使用chatGPT-4 畅聊量子物理学(二)

Omer 量子力学的主导哲学或模型或解释是什么&#xff1f; ChatGPT 量子力学是一门描述微观世界中粒子行为的物理学理论&#xff0c;但它的解释和哲学观点在学术界存在多种不同的观点和争议。以下是几种主要的哲学观点或解释&#xff1a; 哥本哈根解释&#xff1a;这是最为广泛…