【C语言课程设计】通讯录(1.0版本)

news2024/11/27 14:30:15

前言

相信各位对于通讯录都不是很陌生吧。通讯录我们在学校的大作业,课程设计经常会去使用它。那么今天我们将使用C语言来实现一个简单的通讯录。


目录

前言

一、通讯录的需求

二、工程文件的创建

三、通讯录的声明和定义

四、通讯录各函数的声明和定义

五、通讯录的目录和逻辑

六、通讯录功能实现之初始化通讯录

七、通讯录功能实现之增加联系人

八、通讯录功能实现之删除联系人

九、通讯录功能实现之查找联系人

十、通讯录功能实现之修改联系人

十一、通讯录功能实现之排序

十二、通讯录功能实现之打印通讯录

十三、通讯录完整代码(分文件)

test.c文件

Contact.h文件

Contact.c文件

十四、通讯录完整代码(一个文件)

总结


一、通讯录的需求

首先我们要明白一个通讯录要有什么信息呢?

1.要能够存放人的信息:姓名,年龄,性别,地址,电话

2.通讯录能存放多少个人的信息:我们暂时先定为100个人的信息

3.通讯录的功能:

        1>增加联系人

        2>删除指定联系人

        3>查找指定联系人

        4>修改联系人的信息

        5>显示所有联系人的信息

        6>排序(按照年龄、姓名等排序)

上面这些都是通讯录最最最基本的功能。当然,我们可以增加其他的功能,比如说:通讯录要可以保存、查找某个联系人时可以通过多个信息进行筛选、通讯录可以动态自动增容等等

这些设想我们都可以去实现,但是首先,我们要完成最基本的通讯录。就是以上六个功能,之后,我们在这些功能上进行修改,使得我们的通讯录变得更加强大。

二、工程文件的创建

我们采用分文件的形式来完成这个通讯录,当然我们文末会给出一个文件版本的通讯录

test.c文件用来测试通讯录

Contact.c用来完成通讯录的实现

Contact.h用来实现函数的声明

 

三、通讯录的声明和定义

我们想要创建一个通讯录也就是说,要将很多个人的信息给集合起来。那么这就是一个数组。

而每一个人的信息,他又有了很多个类型,我们需要将这些信息给集合起来,这就是一个结构体。

#define MAX 100
#define NAME_MAX 20
#define SEX_MAX 10
#define ADDRESS_MAX 30
#define TELEPHONE_MAX 12


//定义一个结构体类型,这里存放人的信息
typedef struct PeoInfo
{
	char name[NAME_MAX];
	int age;
	char sex[SEX_MAX];
	char address[ADDRESS_MAX];
	char telephone[TELEPHONE_MAX];
}PeoInfo;
//所有人的都放到这里
typedef struct Contact
{
	PeoInfo data[MAX];
	int size;
}Contact;

如上代码所示,我们利用两个结构体,来实现我们的通讯录的声明

PeoInfo这个结构体存放的是每一个人信息,为了方便我们后续的修改,我们使用了宏

每个人的信息都是一个结构体,我们要存储个人,这些人的类型都是相同的。所以我们要使用一个数组,也就是结构体数组。但是呢,我们肯定还需要知道现在存放了几个人的信息了。所以我们还需要一个变量来确定现在的结构体数组里面存放了几个人的信息了。不妨我们就直接把这个结构体数组和这个变量给集合起来。在创建一个结构体。这样方便我们后续的实现。

四、通讯录各函数的声明和定义

我们想,通讯录要实现六个功能。

        

        1>增加联系人

        2>删除指定联系人

        3>查找指定联系人

        4>修改联系人的信息

        5>显示所有联系人的信息

        6>排序(按照年龄、姓名等排序)

这六个功能,我们不妨先给他们声明一些函数。先不去实现。

//初始化通讯录
void InitContact(Contact* pc);
//添加联系人
void AddContact(Contact* pc);
//删除指定联系人
void DelContact(Contact* pc);
//查找指定联系人
void SearchContact(const Contact* pc);
//修改指定联系人
void ModifyContact(Contact* pc);
//排序通讯录
void SortContact(Contact* pc);
//打印通讯录
void ShowContact(const Contact* pc);

需要注意的是,查找和打印并不需要修改通讯录的值,所以我们使用const来保护我们的通讯录

有了这些声明我们假设我们已经实现了,我们可以就来完成一下我们的目录了

五、通讯录的目录和逻辑

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

}
int main()
{
	int input = 0;
	Contact con;
	InitContact(&con);
	do
	{
		menu();
		printf("请输入你的需求>:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("添加联系人\n");
			AddContact(&con);
			break;
		case 2:
			printf("删除指定联系人\n");
			DelContact(&con);
			break;
		case 3:
			printf("查找指定联系人\n");
			SearchContact(&con);
			break;
		case 4:
			printf("修改指定联系人\n");
			ModifyContact(&con);
			break;
		case 5:
			printf("打印所有联系人\n");
			ShowContact(&con);
			break;
		case 6:
			printf("排序联系人\n");
			SortContact(&con);
			break;
		case 0:
			printf("退出通讯录\n");
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
	} while (input);
	return 0;
}

如上代码所示,我们利用do while语句,就可以来实现我们的通讯录的基本逻辑了。同时也写出了我们的代码

六、通讯录功能实现之初始化通讯录

当我们创建好一个通讯录的时候,我们需要将他初始化。

我们可以简单粗暴的直接使用con={0},但是这种方法太粗暴了。

我们完全可以将其封装成一个函数。来实现他

我们这里先断言pc,防止空指针。然后使用memset函数来置空通讯录

//初始化通讯录
void InitContact(Contact* pc)
{
	assert(pc);
	memset(pc->data, 0, sizeof(pc->data));
	pc->size = 0;
}

七、通讯录功能实现之增加联系人

现在我们来实现通讯的添加联系人。

我们同样先断言,然后我们还需要做的就是判断通讯是否满了。如果满了那么直接返回即可

如果没满,那么就正常使用scanf来添加即可。这里我们的参数必须是指针变量。我们要传地址过去才能修改通讯录的值。

//添加联系人
void AddContact(Contact* pc)
{
	assert(pc);
	if (pc->size == MAX)
	{
		printf("通讯录已满,添加失败\n");
		return;
	}
	printf("请输入联系人的姓名:");
	scanf("%s", ((pc->data)[pc->size]).name);
	printf("请输入联系人的年龄:");
	scanf("%d", &((pc->data)[pc->size].age));
	printf("请输入联系人的性别:");
	scanf("%s", (pc->data)[pc->size].sex);
	printf("请输入联系人的地址:");
	scanf("%s", (pc->data)[pc->size].address);
	printf("请输入联系人的电话:");
	scanf("%s", (pc->data)[pc->size].telephone);
	pc->size++;
	printf("恭喜你,添加成功\n");
}

八、通讯录功能实现之删除联系人

添加了联系人,那么与之对应的就是删除操作了

我们删除的基本思路就是,先断言指针,防止空指针

然后如果通讯录空了,那么就不需要删除

我们这里利用姓名来删除联系人。

我们创建一个数组,将输入的联系人姓名放入其中

然后我们创建一个根据名字查找的函数,这个函数的基本思想就是strcmp函数来比较名字,如果名字存在,则返回下标。否则返回-1

我们根据下标来进行删除

删除的时候,我们只需要就后面的元素统一往前挪动一个单位即可,最后不要忘记pc->size--

//在通讯录中通过名字查找一个人,并返回他的下标
int FindByName(const Contact* pc, char* arr)
{
	assert(pc && arr);
	int i = 0;
	for (i = 0; i < pc->size; i++)
	{
		if (strcmp(pc->data[i].name, arr) == 0)
		{
			return i;
		}
	}
	return -1;
}
//删除指定联系人
void DelContact(Contact* pc)
{
	assert(pc);
	if (pc->size == 0)
	{
		printf("通讯录为空,无法删除\n");
		return;
	}
	printf("请输入你要删除的联系人姓名>:");
	char arr[NAME_MAX] = { 0 };
	scanf("%s", arr);
	int pos = FindByName(pc, arr);
	if (pos == -1)
	{
		printf("没有这个人\n");
		return;
	}
	int i = pos;
	for (i = pos; i < pc->size - 1; i++)
	{
		pc->data[i] = pc->data[i + 1];
	}
	pc->size--;
	printf("删除成功\n");
}

九、通讯录功能实现之查找联系人

在查找联系人中,我们同样使用名字来查找,这个就又需要使用我们之前的根据名字返回下标函数了。可以将这个封装成一个函数是很有必要的。

我们直接根据这个下标进行格式化打印即可

//查找指定联系人
void SearchContact(const Contact* pc)
{
	assert(pc);
	if (pc->size == 0)
	{
		printf("通讯录为空,无法查找\n");
		return;
	}
	char arr[NAME_MAX] = { 0 };
	printf("请输入你要查找的名字>:");
	scanf("%s", arr);
	int pos = FindByName(pc, arr);
	if (pos == -1)
	{
		printf("通讯录中不存在这个人\n");
		return;
	}
	printf("%-20s %-4s %-5s %-30s %-12s\n", "姓名", "年龄", "性别", "地址", "电话");
	printf("%-20s %-4d %-5s %-30s %-12s\n",
		pc->data[pos].name,
		pc->data[pos].age,
		pc->data[pos].sex,
		pc->data[pos].address,
		pc->data[pos].telephone);
}

十、通讯录功能实现之修改联系人

我们现在实现的是修改联系人的信息

对于这个函数,我们同样还是根据名字来查找到这个联系人的下标,有了下标,那么修改这个就很简单了。

//修改指定联系人
void ModifyContact(Contact* pc)
{
	assert(pc);
	if (pc->size == 0)
	{
		printf("通讯录为空,无法修改\n");
		return;
	}
	char arr[NAME_MAX] = { 0 };
	printf("请输入你要修改的人的名字\n");
	scanf("%s", arr);
	int pos = FindByName(pc, arr);
	if (pos == -1)
	{
		printf("该联系人不存在\n");
		return;
	}
	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].address);
	printf("请输入联系人的电话:");
	scanf("%s", pc->data[pos].telephone);

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

十一、通讯录功能实现之排序

对于排序我们其实比较熟悉的,我们直接使用快速排序即可。因为我们之前已经介绍过快排的基本使用了。我们这里采用了两种方式来排序,可以供使用者进行选择

值得思考的是,我们也可以利用选择的方式,我们在写一个根据年龄查找下标的函数。然后我们就可以选择通过年龄来找到我们需要修改的联系人,并且返回他的下标了。这样我们查找的功能就更加强大了

void cmp_by_name(void* e1, void* e2)
{
	return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}
void cmp_by_age(void* e1, void* e2)
{
	return ((PeoInfo*)e1)->age - ((PeoInfo*)e2)->age;
}
//排序通讯录
void SortContact(Contact* pc)
{
	assert(pc);
	int input = 0;
	printf("请选择你需要按姓名排序还是按照年龄排序\n");
	printf("按照姓名排序请输入1,按照年龄排序请输入2 :\n");
	scanf("%d", &input);
	if (input == 1)
		qsort(pc, pc->size, sizeof(PeoInfo), cmp_by_name);
	if (input == 2)
		qsort(pc, pc->size, sizeof(PeoInfo), cmp_by_age);
	printf("排序成功\n");
}

十二、通讯录功能实现之打印通讯录

我们对通讯录有了那么多的实现,那么我们也得看到我们的实现后的样子吧,所以我们就很有必要完成一个打印函数。这个函数的实现也很简单,就是利用遍历的思想即可

//打印通讯录
void ShowContact(const Contact* pc)
{
	assert(pc);
	int i = 0;
	printf("%-20s %-4s %-5s %-30s %-12s\n","姓名","年龄","性别","地址","电话");
	for (i = 0; i < pc->size; i++)
	{
		printf("%-20s %-4d %-5s %-30s %-12s\n",
			pc->data[i].name,
			pc->data[i].age,
			pc->data[i].sex, 
			pc->data[i].address,
			pc->data[i].telephone);
	}

}

十三、通讯录完整代码(分文件)

test.c文件

#define _CRT_SECURE_NO_WARNINGS 1
#include"Contact.h"
void menu()
{
	printf("*************************\n");
	printf("****      1.Add      ****\n");
	printf("****      2.Del      ****\n");
	printf("****      3.Search   ****\n");
	printf("****      4.Modify   ****\n");
	printf("****      5.Show     ****\n");
	printf("****      6.Sort     ****\n");
	printf("****      0.exit     ****\n");
	printf("*************************\n");

}
int main()
{
	int input = 0;
	Contact con;
	InitContact(&con);
	do
	{
		menu();
		printf("请输入你的需求>:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("添加联系人\n");
			AddContact(&con);
			break;
		case 2:
			printf("删除指定联系人\n");
			DelContact(&con);
			break;
		case 3:
			printf("查找指定联系人\n");
			SearchContact(&con);
			break;
		case 4:
			printf("修改指定联系人\n");
			ModifyContact(&con);
			break;
		case 5:
			printf("打印所有联系人\n");
			ShowContact(&con);
			break;
		case 6:
			printf("排序联系人\n");
			SortContact(&con);
			break;
		case 0:
			printf("退出通讯录\n");
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
	} while (input);
	return 0;
}

Contact.h文件

#pragma once
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>
#define MAX 100
#define NAME_MAX 20
#define SEX_MAX 10
#define ADDRESS_MAX 30
#define TELEPHONE_MAX 12


//定义一个结构体类型,这里存放人的信息
typedef struct PeoInfo
{
	char name[NAME_MAX];
	int age;
	char sex[SEX_MAX];
	char address[ADDRESS_MAX];
	char telephone[TELEPHONE_MAX];
}PeoInfo;
//所有人的都放到这里
typedef struct Contact
{
	PeoInfo data[MAX];
	int size;
}Contact;
//初始化通讯录
void InitContact(Contact* pc);
//添加联系人
void AddContact(Contact* pc);
//删除指定联系人
void DelContact(Contact* pc);
//查找指定联系人
void SearchContact(const Contact* pc);
//修改指定联系人
void ModifyContact(Contact* pc);
//排序通讯录
void SortContact(Contact* pc);
//打印通讯录
void ShowContact(const Contact* pc);

Contact.c文件

#define _CRT_SECURE_NO_WARNINGS 1
#include"Contact.h"
//初始化通讯录
void InitContact(Contact* pc)
{
	assert(pc);
	memset(pc->data, 0, sizeof(pc->data));
	pc->size = 0;
}
//添加联系人
void AddContact(Contact* pc)
{
	assert(pc);
	if (pc->size == MAX)
	{
		printf("通讯录已满,添加失败\n");
		return;
	}
	printf("请输入联系人的姓名:");
	scanf("%s", ((pc->data)[pc->size]).name);
	printf("请输入联系人的年龄:");
	scanf("%d", &((pc->data)[pc->size].age));
	printf("请输入联系人的性别:");
	scanf("%s", (pc->data)[pc->size].sex);
	printf("请输入联系人的地址:");
	scanf("%s", (pc->data)[pc->size].address);
	printf("请输入联系人的电话:");
	scanf("%s", (pc->data)[pc->size].telephone);
	pc->size++;
	printf("恭喜你,添加成功\n");
}
//在通讯录中通过名字查找一个人,并返回他的下标
int FindByName(const Contact* pc, char* arr)
{
	assert(pc && arr);
	int i = 0;
	for (i = 0; i < pc->size; i++)
	{
		if (strcmp(pc->data[i].name, arr) == 0)
		{
			return i;
		}
	}
	return -1;
}
//删除指定联系人
void DelContact(Contact* pc)
{
	assert(pc);
	if (pc->size == 0)
	{
		printf("通讯录为空,无法删除\n");
		return;
	}
	printf("请输入你要删除的联系人姓名>:");
	char arr[NAME_MAX] = { 0 };
	scanf("%s", arr);
	int pos = FindByName(pc, arr);
	if (pos == -1)
	{
		printf("没有这个人\n");
		return;
	}
	int i = pos;
	for (i = pos; i < pc->size - 1; i++)
	{
		pc->data[i] = pc->data[i + 1];
	}
	pc->size--;
	printf("删除成功\n");
}
//查找指定联系人
void SearchContact(const Contact* pc)
{
	assert(pc);
	if (pc->size == 0)
	{
		printf("通讯录为空,无法查找\n");
		return;
	}
	char arr[NAME_MAX] = { 0 };
	printf("请输入你要查找的名字>:");
	scanf("%s", arr);
	int pos = FindByName(pc, arr);
	if (pos == -1)
	{
		printf("通讯录中不存在这个人\n");
		return;
	}
	printf("%-20s %-4s %-5s %-30s %-12s\n", "姓名", "年龄", "性别", "地址", "电话");
	printf("%-20s %-4d %-5s %-30s %-12s\n",
		pc->data[pos].name,
		pc->data[pos].age,
		pc->data[pos].sex,
		pc->data[pos].address,
		pc->data[pos].telephone);
}
//修改指定联系人
void ModifyContact(Contact* pc)
{
	assert(pc);
	if (pc->size == 0)
	{
		printf("通讯录为空,无法修改\n");
		return;
	}
	char arr[NAME_MAX] = { 0 };
	printf("请输入你要修改的人的名字\n");
	scanf("%s", arr);
	int pos = FindByName(pc, arr);
	if (pos == -1)
	{
		printf("该联系人不存在\n");
		return;
	}
	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].address);
	printf("请输入联系人的电话:");
	scanf("%s", pc->data[pos].telephone);

	printf("修改成功\n");
}
void cmp_by_name(void* e1, void* e2)
{
	return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}
void cmp_by_age(void* e1, void* e2)
{
	return ((PeoInfo*)e1)->age - ((PeoInfo*)e2)->age;
}
//排序通讯录
void SortContact(Contact* pc)
{
	assert(pc);
	int input = 0;
	printf("请选择你需要按姓名排序还是按照年龄排序\n");
	printf("按照姓名排序请输入1,按照年龄排序请输入2 :\n");
	scanf("%d", &input);
	if (input == 1)
		qsort(pc, pc->size, sizeof(PeoInfo), cmp_by_name);
	if (input == 2)
		qsort(pc, pc->size, sizeof(PeoInfo), cmp_by_age);
	printf("排序成功\n");
}
//打印通讯录
void ShowContact(const Contact* pc)
{
	assert(pc);
	int i = 0;
	printf("%-20s %-4s %-5s %-30s %-12s\n","姓名","年龄","性别","地址","电话");
	for (i = 0; i < pc->size; i++)
	{
		printf("%-20s %-4d %-5s %-30s %-12s\n",
			pc->data[i].name,
			pc->data[i].age,
			pc->data[i].sex, 
			pc->data[i].address,
			pc->data[i].telephone);
	}

}

十四、通讯录完整代码(一个文件)

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>
#define MAX 100
#define NAME_MAX 20
#define SEX_MAX 10
#define ADDRESS_MAX 30
#define TELEPHONE_MAX 12


//定义一个结构体类型,这里存放人的信息
typedef struct PeoInfo
{
	char name[NAME_MAX];
	int age;
	char sex[SEX_MAX];
	char address[ADDRESS_MAX];
	char telephone[TELEPHONE_MAX];
}PeoInfo;
//所有人的都放到这里
typedef struct Contact
{
	PeoInfo data[MAX];
	int size;
}Contact;
//初始化通讯录
void InitContact(Contact* pc);
//添加联系人
void AddContact(Contact* pc);
//删除指定联系人
void DelContact(Contact* pc);
//查找指定联系人
void SearchContact(const Contact* pc);
//修改指定联系人
void ModifyContact(Contact* pc);
//排序通讯录
void SortContact(Contact* pc);
//打印通讯录
void ShowContact(const Contact* pc);


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

}
int main()
{
	int input = 0;
	Contact con;
	InitContact(&con);
	do
	{
		menu();
		printf("请输入你的需求>:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("添加联系人\n");
			AddContact(&con);
			break;
		case 2:
			printf("删除指定联系人\n");
			DelContact(&con);
			break;
		case 3:
			printf("查找指定联系人\n");
			SearchContact(&con);
			break;
		case 4:
			printf("修改指定联系人\n");
			ModifyContact(&con);
			break;
		case 5:
			printf("打印所有联系人\n");
			ShowContact(&con);
			break;
		case 6:
			printf("排序联系人\n");
			SortContact(&con);
			break;
		case 0:
			printf("退出通讯录\n");
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
	} while (input);
	return 0;
}

//初始化通讯录
void InitContact(Contact* pc)
{
	assert(pc);
	memset(pc->data, 0, sizeof(pc->data));
	pc->size = 0;
}
//添加联系人
void AddContact(Contact* pc)
{
	assert(pc);
	if (pc->size == MAX)
	{
		printf("通讯录已满,添加失败\n");
		return;
	}
	printf("请输入联系人的姓名:");
	scanf("%s", ((pc->data)[pc->size]).name);
	printf("请输入联系人的年龄:");
	scanf("%d", &((pc->data)[pc->size].age));
	printf("请输入联系人的性别:");
	scanf("%s", (pc->data)[pc->size].sex);
	printf("请输入联系人的地址:");
	scanf("%s", (pc->data)[pc->size].address);
	printf("请输入联系人的电话:");
	scanf("%s", (pc->data)[pc->size].telephone);
	pc->size++;
	printf("恭喜你,添加成功\n");
}
//在通讯录中通过名字查找一个人,并返回他的下标
int FindByName(const Contact* pc, char* arr)
{
	assert(pc && arr);
	int i = 0;
	for (i = 0; i < pc->size; i++)
	{
		if (strcmp(pc->data[i].name, arr) == 0)
		{
			return i;
		}
	}
	return -1;
}
//删除指定联系人
void DelContact(Contact* pc)
{
	assert(pc);
	if (pc->size == 0)
	{
		printf("通讯录为空,无法删除\n");
		return;
	}
	printf("请输入你要删除的联系人姓名>:");
	char arr[NAME_MAX] = { 0 };
	scanf("%s", arr);
	int pos = FindByName(pc, arr);
	if (pos == -1)
	{
		printf("没有这个人\n");
		return;
	}
	int i = pos;
	for (i = pos; i < pc->size - 1; i++)
	{
		pc->data[i] = pc->data[i + 1];
	}
	pc->size--;
	printf("删除成功\n");
}
//查找指定联系人
void SearchContact(const Contact* pc)
{
	assert(pc);
	if (pc->size == 0)
	{
		printf("通讯录为空,无法查找\n");
		return;
	}
	char arr[NAME_MAX] = { 0 };
	printf("请输入你要查找的名字>:");
	scanf("%s", arr);
	int pos = FindByName(pc, arr);
	if (pos == -1)
	{
		printf("通讯录中不存在这个人\n");
		return;
	}
	printf("%-20s %-4s %-5s %-30s %-12s\n", "姓名", "年龄", "性别", "地址", "电话");
	printf("%-20s %-4d %-5s %-30s %-12s\n",
		pc->data[pos].name,
		pc->data[pos].age,
		pc->data[pos].sex,
		pc->data[pos].address,
		pc->data[pos].telephone);
}
//修改指定联系人
void ModifyContact(Contact* pc)
{
	assert(pc);
	if (pc->size == 0)
	{
		printf("通讯录为空,无法修改\n");
		return;
	}
	char arr[NAME_MAX] = { 0 };
	printf("请输入你要修改的人的名字\n");
	scanf("%s", arr);
	int pos = FindByName(pc, arr);
	if (pos == -1)
	{
		printf("该联系人不存在\n");
		return;
	}
	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].address);
	printf("请输入联系人的电话:");
	scanf("%s", pc->data[pos].telephone);

	printf("修改成功\n");
}
void cmp_by_name(void* e1, void* e2)
{
	return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}
void cmp_by_age(void* e1, void* e2)
{
	return ((PeoInfo*)e1)->age - ((PeoInfo*)e2)->age;
}
//排序通讯录
void SortContact(Contact* pc)
{
	assert(pc);
	int input = 0;
	printf("请选择你需要按姓名排序还是按照年龄排序\n");
	printf("按照姓名排序请输入1,按照年龄排序请输入2 :\n");
	scanf("%d", &input);
	if (input == 1)
		qsort(pc, pc->size, sizeof(PeoInfo), cmp_by_name);
	if (input == 2)
		qsort(pc, pc->size, sizeof(PeoInfo), cmp_by_age);
	printf("排序成功\n");
}
//打印通讯录
void ShowContact(const Contact* pc)
{
	assert(pc);
	int i = 0;
	printf("%-20s %-4s %-5s %-30s %-12s\n", "姓名", "年龄", "性别", "地址", "电话");
	for (i = 0; i < pc->size; i++)
	{
		printf("%-20s %-4d %-5s %-30s %-12s\n",
			pc->data[i].name,
			pc->data[i].age,
			pc->data[i].sex,
			pc->data[i].address,
			pc->data[i].telephone);
	}

}


总结

我们本节实现了一个简单的通讯录,但是要注意的是,这个通讯录其实并不完善。因为他的容量是死的。我们希望可以实现一个可以动态扩容的通讯录。其次他的一个缺陷就是关闭了这个文件之后,在打开就会发现,之前的信息不见了。我们希望可以实现一个不会消失数据的通讯录。这些我们都将在后面的文章中实现

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mysql入门技能树-数据查询-练习篇

SELECT 下列 SQL 语句&#xff0c;哪一项不合法&#xff1f; 答案是&#xff1a;C select now(),3.14 now() |3.14| ----------------------- 2023-01-16 16:47:04|3.14|MySQL查询表中所有的数据可以通过“SELECT * 通配符”或者“SELECT 所有字段”实现。 SE…

hadoop3.x源码编译及cmake的问题解决:CMake failed with error code 1

一、准备工作 基础环境&#xff1a;centos7 &#xff08;1&#xff09;官方源码中编译之前对基础环境及版本的要求&#xff08;重点是红色部分&#xff09; Requirements: * Unix System* JDK 1.8 * Maven 3.3 or later * ProtocolBuffer 2.5.0 * CMake 3.1 or newer (if com…

OSCP-Vulnhub靶机记录-Hacker_Kid-v1.0.1

Vulnhub靶机记录-Hacker_Kid-v1.0.1介绍&安装信息收集页面源代码DIG信息收集xxe漏洞探测9999端口SSTI模板注入发现具有Capabilities特殊操作权限的程序原理介绍&安装 靶机名称&#xff1a;Hacker_Kid-v1.0.1 靶机难度&#xff1a;中等 虚拟机环境&#xff1a;此靶机推…

【Linux】线程互斥

目录&#x1f308;前言&#x1f338;1、Linux线程互斥&#x1f367;1.1、线程间互斥相关背景概念&#x1f368;1.2、互斥量(锁)相关背景&#x1f36f;1.3、互斥量(锁)相关API&#x1f36f;1.3.1、初始化和销毁互斥锁&#x1f370;1.3.2、互斥量加锁和解锁&#x1f372;1.3.3、互…

Python爬虫403错误的解决方案

前言程序使用一段时间后会遇到HTTP Error 403: Forbidden错误。 因为在短时间内直接使用Get获取大量数据&#xff0c;会被服务器认为在对它进行攻击&#xff0c;所以拒绝我们的请求&#xff0c;自动把电脑IP封了。 解决这个问题有两种方法。一是将请求加以包装&#xff0c;变成…

1.浮动float

提示&#xff1a;如果多一个盒子&#xff08;都设置浮动&#xff0c;则它们会按照属性值一行内显示并且顶端对齐排列&#xff09; 注意&#xff1a; 浮动的元素是互相贴靠在一起的&#xff0c;&#xff08;没有缝隙&#xff09;&#xff0c;如果父级宽度装下这些浮动盒子&#…

MyBatis 详解 (2) -- 增删改操作

MyBatis 详解 2 -- 增删改操作前言一、准备工作1.1 创建数据库和表1.2 添加实体类1.3 添加 mapper 接口 (数据持久层)1.4 创建与接口对应的 xml 文件二、增加操作2.1 默认返回受影响的行数2.2 特殊的新增&#xff1a;返回自增 id三、删除操作四、修改操作五、实现完整交互5.1 添…

爆肝9万字,我已从小白晋升ARM嵌入式工程师!带你从零熟悉常用的M4嵌入式功能,建议收藏(含码源)

&#x1f4da; 前言 &#x1f4d1;博客主页&#xff1a;丘比特惩罚陆 &#x1f496;欢迎关注&#xff1a;点赞收藏⭐留言✒ &#x1f4ac;系列专栏&#xff1a;web前端、嵌入式、笔记专栏 &#x1f3ae; 加入社区&#xff1a; 丘比特惩罚陆 &#x1f947;人生格言&#xff1a;选…

【教学赛】金融数据分析赛题1:银行客户认购产品预测(0.9676)

本文是对天池教学赛&#xff0c;银行客户认购产品预测的记录&#xff0c;教学赛网址如下&#xff1a; 【教学赛】金融数据分析赛题1&#xff1a;银行客户认购产品预测_学习赛_天池大赛-阿里云天池 1. 读取数据 import pandas as pd# 加载数据 train pd.read_csv(train.csv) …

P5587 打字练习————C++

题目 打字练习 题目描述 R 君在练习打字。 有这样一个打字练习网站&#xff0c;给定一个范文和输入框&#xff0c;会根据你的输入计算准确率和打字速度。可以输入的字符有小写字母、空格和 .&#xff08;英文句号&#xff09;&#xff0c;输入字符后&#xff0c;光标也会跟…

c语言小练pintia11-20

11.计算平均分已知某位学生的数学、英语和计算机课程的成绩分别是87分、72分和93分&#xff0c;求该生3门课程的平均成绩&#xff08;结果按整型输出&#xff09;。输入格式&#xff1a;本题无输入输出格式&#xff1a;按照下列格式输出结果&#xff1a;math 87, eng 72, com…

深耕地市区县市场,新华三智行中国走新路

2022年就这样结束了&#xff0c;但是企业数字化的进程从未结束。回顾这一年&#xff0c;对于任何企业而言&#xff0c;数字化优先的战略仍然在继续。不仅如此&#xff0c;数字化走向地市区县市场&#xff0c;带来了更多的机遇和发展&#xff0c;让我们看到了中国的数字经济还有…

Flurry iOS端调研和使用

Flurry iOS端调研使用 flurry官方资料较少&#xff0c;且只有英文文档没有代码demo。公司项目确定要用Flurry&#xff0c;所以深入调研&#xff0c;顺便记录过程。有需要的小伙伴也可以顺便参考 一.创建应用拿api_key 官网&#xff1a;https://www.flurry.com/ 用邮箱去官网…

【目标检测】55、YOLOv8 | YOLOv5 团队 Ultralytics 再次出手,又实现了 SOTA

文章目录一、YOLO 系列算法的简单回顾二、YOLOv8 简介2.1 安装和简单使用2.2 Ultralytics HUB2.2.1 Upload Dataset2.3 YOLOv8 主要改动三、YOLOv8 细节详述论文&#xff1a;暂无 官方文档&#xff1a;https://docs.ultralytics.com/ 代码&#xff1a;https://github.com/ult…

【算法数据结构初阶篇】:链表问题

一、反转单双链表 一、数据结构图 二、代码演示 public class Code01_ReverseList {public static class Node {public int value;public Node next;public Node(int data) {value data;}}public static class DoubleNode {public int value;public DoubleNode last;public …

Spring Cloud Gateway从注册中心自动注册配置路由信息

环境信息Spring Boot&#xff1a;2.0.8.RELEASESpring Boot内置的tomcat&#xff1a;tomcat-embed-core 8.5.37Spring Cloud Gateway&#xff1a;2.0.4.RELEASENacos&#xff1a;2.0.4.RELEASE需求Spring Cloud Gateway注册到注册中心&#xff08;这里是Nacos&#xff0c;其它注…

Spring学习系列(二)

Spring_特殊值的注入问题和各种类型的自动装配1.set两种方式的区别第4中赋值方式&#xff1a;自动装配&#xff08;只适用于ref类型&#xff09;使用注解定义bean1.set两种方式的区别 &#xff08;1&#xff09;把值写到value属性里面&#xff0c;必须加引号&#xff0c;写到子…

【学习】计算机系统硬件和数据结构

学习内容描述&#xff1a; 1、CPU包含哪些部分&#xff1f; 2、数据结构基础知识。 重点知识&#xff1a; 1、CPU(中央处理器&#xff0c;Central Processing Unit) 主要包括运算器、控制器两大部件&#xff1b;内部结构包含控制单元、运算单元、存储单元和时钟等几个主要部…

虚拟直播(虚拟场景直播)要怎么做?

阿酷TONY / 2022-11-21 / 长沙 绿幕抠像 虚拟场景&#xff08;三维场景&#xff09;实时渲染&#xff0c;来一场虚拟直播。 附案例效果&#xff1a;PC端案例、移动端案例效果。 目录 1. 绿幕虚拟直播间 2. 虚拟场景(炫酷舞台) 3. 案例&#xff1a;PC端 4. 案例&#xff1a…

光纤内窥镜物镜光学设计

光纤内窥镜物镜光学设计 工作原理 典型的光纤传像束内窥镜主要由前置物镜、光纤传像束、目镜/耦接镜、 探测器等组成&#xff0c;如图1所示。通过物镜把目标成像于光纤传像束的前端面上&#xff0c;该端面上的图像被离散分布的大量光纤采样&#xff0c;每根光纤都有良好的光学…