通讯录实现【C语言】

news2024/12/24 9:18:09

目录

前言

一、整体逻辑分析

二、实现步骤

1、创建菜单和多次操作问题

2、创建通讯录

3、初始化通讯录

4、添加联系人

5、显示联系人

6、删除指定联系人

​7、查找指定联系人

8、修改联系人信息

9、排序联系人信息

三、全部源码


前言

我们上期已经详细的介绍了自定义类型,本期我们来用学过的知识来做个小项目来练习练习。本期我们将用C语言实现通讯录静态版!后期介绍了动态内存管理和文件操作我们将会在此版本的基础上进行优化改进!

一、整体逻辑分析

我们还和以前实现三子棋和扫雷小项目一样,先对整体工程的逻辑尽可能详细的梳理,否则一开就是一顿狂敲,最后一走发现全是Bug这样就不好了!我们一开始尽可能的分析清楚,后面即使出现了问题也能快速确定!本期还是和往期一样采用多文件编程!OK,我们下面一起来梳理一下这个小项目的基本实现逻辑:

1、创建菜单和多次操作问题

2、创建通讯录

3、通讯录的初始化以及增删查改等操作

二、实现步骤

1、创建菜单和多次操作问题

我们期望当我们进行对通讯录操作时可以给我们在进行操作前给一个菜单功能我们操作!考虑到后面还要多次操作通讯录(增删查改等)我们结合起来很快想到用do..while循环处理最为合理,这里以前写过两三遍了我们直接上代码:

#include"contact.h"

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");
}

void test()
{
	int input = 0;
	do
	{
		menu();
		printf("请选择操作数:> ");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			//add
			break;
		case 2:
			//del
			break;
		case 3:
			//search
			break;
		case 4:
			//modify
			break;
		case 5:
			//show
			break;
		case 6:
			//sort
			break;
		case 0:
			printf("退出成功!\n");
			break;
		default:
			printf("选择数非法!\n");
			break;
		}

	} while (input);
}

int main()
{
	test();
	return 0;
}

看效果:

2、创建通讯录

我们在对通讯录进行各种操作前先得有个通讯录吧!通讯录的本质还是描述一个人的属性例如:姓名、年龄、性别、电话、住址等!这些都是不同的类型,我们很容易想到用结构体就能解决!但这只是描述一个人,你的通讯录不可能只有一个人吧应该是有很多个!而这些联系人又是同一类型,因此采用结构体数组来创建通讯录!

typedef struct PeoInfo
{
	char name[20];
	int age;
	char sex[5];
	char tele[15];
	char addr[20];
}PeoInfo;

这就是描述一个人基本属性的结构体!当创建好了这个结构体后,我们就可以在test.c这个文件中do..while循环那里可以创建结构体数组来作为通讯录了!

但这样写会有个问题就是,当你存入或删除联系人后想打印出来看看是此时通讯录中的联系人时应该打印多少?我们还想不知道。所以这里我们还得再定义一个变量sz来记录通讯录的大小!

其实我们发现,sz不仅是可以记录通讯录的大小,而且增加联系人的时候只需要增加到sz位置即可,增加一个sz++,当删除一个sz--;这样其实 sz和通讯录是绑定在一起的,我们不妨在对通讯录进行一层封装,把他也封装成一个结构体,一个成员是PeoInfo结构体数组,一个是记录通讯录大小的sz:

typedef struct PeoInfo
{
	char name[20];
	int age;
	char sex[5];
	char tele[15];
	char addr[20];
}PeoInfo;


typedef struct Contact
{
	PeoInfo data[100];
	int sz;
}Contact;

然后再在test.c文件中创建即可!

OK!这个创建通讯录记好了!其实这里还可已在稍微优化一下:我们发现两个结构体中都出现了大量的常数,我们万一后期需求有变,这些都得改!因此为了后期修改方便,我们把这些都改成#define的常量,后期修改起来容易!这里你可能会说上期不是介绍了枚举吗,这里正好是多个常量枚举不是更好吗?这里枚举确实可以达到目的,但枚举是在没开始前就能列举出来所有可能,我们这个可不是!所以,这里不用枚举!

#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 15
#define ADDR_MAX 20
#define MAX 100

typedef struct PeoInfo
{
	char name[NAME_MAX];
	int age;
	char sex[SEX_MAX];
	char tele[TELE_MAX];
	char addr[ADDR_MAX];
}PeoInfo;


typedef struct Contact
{
	PeoInfo data[MAX];
	int sz;
}Contact;

这样才是当前逻辑下的最优代码!

3、初始化通讯录

当我们创建好了通讯录后我们先对其进行一个初始化!把结构体数组的每个元素都初始化为0,通讯录大小也置为0!因为我们要改变结构体的内容所以应该传地址!我们这里采用的是memset这个函数直接初始化为0,也可以用个循环来初始化!不了解memset的点击memset

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

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

4、添加联系人

我们前面已经说过了,只需要在sz的位置增加即可!但要考虑通讯录满的情况!

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].tele);
	printf("请输入联系人住址:> ");
	scanf("%s", pc->data[pc->sz].addr);
	pc->sz++;

	printf("添加成功!\n");
}

OK,我们下面先来写一个显示联系人,来验证一下是否添加成功!

5、显示联系人

显示联系人就是把通讯录中的联系人打印在控制台!

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

	printf("%-s\t%-s\t%-5s\t%-15s\t%-20s\n", "姓名", "年龄", "性别", "电话", "住址");
	for (int i = 0; i < pc->sz; i++)
	{
		printf("%-s\t%-d\t%-5s\t%-15s\t%-20s\n",
			pc->data[i].name,
			pc->data[i].age,
			pc->data[i].sex,
			pc->data[i].tele,
			pc->data[i].addr
		);
	}
}

OK,我们来看看是否添加成功以及显示联系人!

OK,添加联系人和显示联系人都成功了!说明我们上面逻辑没有问题!

6、删除指定联系人

我们输入要删除的人的姓名,进行查找,找到了删除,否则输出没有此联系人!注意考虑通讯录为空的情况!这里提到了查找,这个查找和通讯录的那个查找有点不一样,这个是查找后返回下标即可,那个是还要打印联系人信息功能不一样。因此我们单独在封装一个函数!

//查找要删除的人并返回下标
int FindContact(const Contact* pc, const char* name)
{
	for (int i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
		{
			return i;//找到了
		}
	}

	return -1;//没找到
}

//删除联系人
void DelContact(Contact* pc)
{
	assert(pc);
    //通讯录为空
	if (pc->sz == 0)
	{
		printf("通讯录为空,无法删除!\n");
		return;
	}

	char name[NAME_MAX] = { 0 };
	printf("请输入要删除人的姓名:> ");
	scanf("%s", name);

	int pos = FindContact(pc, name);

	if (pos != -1)
	{
		//删除
		for (int i = pos; i < pc->sz - 1; i++)
		{
			pc->data[i] = pc->data[i + 1];
		}

		pc->sz--;
		printf("成功删除联系人!\n");
	}
	else
	{
		printf("没有此联系人!\n");
	}
}

这里要注意的是比较字符串要用strcmp,不能用 == 这个我们在字符串函数和内存函数那一期详细介绍过!另外注意删除的时候那里下标越界问题!

看效果:

 7、查找指定联系人

查找指定联系人还是先按指定方式进行查找, 找到了打印,否则输出没有此联系人!这里显示一个联系人的这个里后面修改联系人也可能要用所以我们为了方便把他封装成一个函数后面直接调用即可!


//显示单个联系人信息
void Print(const Contact* pc, int pos)
{
	assert(pc);

	printf("%-s\t%-s\t%-5s\t%-15s\t%-20s\n", "姓名", "年龄", "性别", "电话", "住址");

	printf("%-s\t%-d\t%-5s\t%-15s\t%-20s\n",
		pc->data[pos].name,
		pc->data[pos].age,
		pc->data[pos].sex,
		pc->data[pos].tele,
		pc->data[pos].addr);

}

//查找指定联系人
void Search(const Contact* pc)
{
	assert(pc);

	char name[NAME_MAX] = { 0 };
	printf("请输入要查找联系人姓名:> ");
	scanf("%s", name);

	int pos = -1;//初始化为-1表示没有此联系人
	for (int i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
		{
			pos = i;//找到了
			break;
		}
	}

	if (pos != -1)
	{
		Print(pc, pos);
	}
	else
	{
		printf("没有此联系人!\n");
	}
}

其实还可以在简洁一点,上面已经实现了FindContact我们可以用一下:

void Search(const Contact* pc)
{
	assert(pc);

	char name[NAME_MAX] = { 0 };
	printf("请输入要查找联系人姓名:> ");
	scanf("%s", name);

	int pos = FindContact(pc, name);

	if (pos != -1)
	{
		Print(pc, pos);
	}
	else
	{
		printf("没有此联系人!\n");
	}
}

看效果:

8、修改联系人信息

修改联系人信息这块就有很多可能,比如只修改一项例如名字或性别等,也有可能修改多项例如名字、年龄等,也有可能得全部修改这几种情况。当我们要修改之前群殴我们能还是期望有一个菜单供我们选择,当修改完一项后我们可能还要继续修改。基于此我们采用和test.c文件中得do...while循环+菜单!

//修改联系人信息菜单
void menu1()
{
    system("cls");
	printf("*****************************************\n");
	printf("********* 1. name     2. age   **********\n");
	printf("********* 3. sex      4. tele  **********\n");
	printf("********* 5. addr     6. all   **********\n");
	printf("********* 0. exit              **********\n");
	printf("*****************************************\n");
}

//修改名字
void ModName(Contact* pc, int ret)
{
	assert(pc);

	printf("请输入修改后联系人姓名:> ");
	scanf("%s", pc->data[ret].name);
	printf("修改成功!\n");
}

//修改年龄
void ModAge(Contact* pc, int ret)
{
	assert(pc);

	printf("请输入修改后联系人年龄:> ");
	scanf("%d", &pc->data[ret].age);
	printf("修改成功!\n");
}

//修改性别
void ModSex(Contact* pc, int ret)
{
	assert(pc);

	printf("请输入修改后联系人性别:> ");
	scanf("%s", &pc->data[ret].sex);
	printf("修改成功!\n");
}

//修改电话
void ModTele(Contact* pc, int ret)
{
	assert(pc);

	printf("请输入修改后联系人电话:> ");
	scanf("%s", &pc->data[ret].tele);
	printf("修改成功!\n");
}

//修改住址
void ModAddr(Contact* pc, int ret)
{
	assert(pc);

	printf("请输入修改后联系人住址:> ");
	scanf("%s", &pc->data[ret].addr);
	printf("修改成功!\n");
}


void ModAll(Contact* pc, int ret)
{
	assert(pc);

	printf("请输入联系人姓名:> ");
	scanf("%s", pc->data[ret].name);
	printf("请输入联系人年龄:> ");
	scanf("%d", &pc->data[ret].age);
	printf("请输入联系人性别:> ");
	scanf("%s", pc->data[ret].sex);
	printf("请输入联系人电话:> ");
	scanf("%s", pc->data[ret].tele);
	printf("请输入联系人住址:> ");
	scanf("%s", pc->data[ret].addr);
	
	printf("修改成功!\n");
}


//修改联系人
void ModContact(Contact* pc)
{
	assert(pc);
	//判断是否为空
	if (pc->sz == 0)
	{
		printf("通讯录为空,无法修改!\n");
		return;
	}

	char name[NAME_MAX] = { 0 };
	printf("请输入要修改系人姓名:> ");
	scanf("%s", name);
	//判断是否有该联系人
	int ret = FindContact(pc, name);
	
	//有该联系人
	if (ret != -1)
	{
		int n = 0;
		do
		{
			menu1();
			printf("请选择修改内容:> ");
			scanf("%d", &n);
			//修改
			switch (n)
			{
			case 1:
				ModName(pc,ret);
				break;
			case 2:
				ModAge(pc, ret);
				break;
			case 3:
				ModSex(pc, ret);
				break;
			case 4:
				ModTele(pc, ret);
				break;
			case 5:
				ModAddr(pc, ret);
				break;
			case 6:
				ModAll(pc, ret);
				break;
			case 0:
				printf("修改结束!\n");
				break;
			default:
				printf("选择数非法!\n");
				break;
			}

		} while (n);
	}
	else
	{
		printf("没有此联系人!\n");
	}
}

看效果:(小编做了清屏)

修改前:

 修改后:

OK,还是比较成功的!我们再来进行对他实现一下排序!

9、排序联系人信息

我们上面已经实现了通讯录的增删查改的基本功能!我们想让他再有一个排序功能,比如按名字排序,或年龄排序!我们在指针进阶那块介绍过回调函数,这里我们用qsort进行对通讯录排序!我们期望还是和上面一样一开始有个菜单选择!


//排序菜单
void menu2()
{
	system("cls");
	printf("**********************************\n");
	printf("***** 1. name    2. age **********\n");
	printf("**********************************\n");
}

//名字比较函数
int cmp_name(const void* str1, const void* str2)
{
	//return strcmp(((PeoInfo*)str1)->name, ((PeoInfo*)str2)->name);
	return strcmp((((Contact*)str1)->data)->name, (((Contact*)str2)->data)->name);
}

//名字排序
void SortName(Contact* pc)
{
	qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_name);
}

//年龄比较函数
int cmp_age(const void* str1, const void* str2)
{

	//return ((PeoInfo*)str1)->age - ((PeoInfo*)str2)->age;
	return (((Contact*)str1)->data)->age - (((Contact*)str2)->data)->age;
}
//年龄排序
void SortAge(Contact* pc)
{
	qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_age);
}

//排序联系人信息
void SortContact(Contact* pc)
{
	assert(pc);
	//判断为空
	if (pc->sz == 0)
	{
		printf("通讯录为空,无法排序!\n");
		Sleep(3000);
		system("cls");
		return;
	}


	menu2();
	int n = 0;
	printf("请选择排序方式:> ");
	scanf("%d", &n);
	//排序
	switch (n)
	{
	case 1:
		SortName(pc);
		system("cls");
		printf("排序成功!\n");
		break;
	case 2:
		SortAge(pc);
		system("cls");
		printf("排序成功!\n");
		break;
	default:
		printf("选择数非法!\n");
		Sleep(3000);
		system("cls");
		break;
	}
}

看效果:

排序前(年龄):

 排序后(年龄):

排序前(名字):

 排序后(名字):

OK,实现了排序!

三、全部源码

 contact.h

#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>
#include<windows.h>

#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 15
#define ADDR_MAX 20
#define MAX 100

typedef struct PeoInfo
{
	char name[NAME_MAX];
	int age;
	char sex[SEX_MAX];
	char tele[TELE_MAX];
	char addr[ADDR_MAX];
}PeoInfo;


typedef struct Contact
{
	PeoInfo data[MAX];
	int sz;
}Contact;


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

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

//显示联系人
void ShowContact(const Contact* pc);

//删除联系人
void DelContact(Contact* pc);

//查找指定联系人
void Search(const Contact* pc);

//修改联系人
void ModContact(Contact* pc);

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


contact.c

#include"contact.h"

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

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

//增加联系人
void AddContact(Contact* pc) 
{
	assert(pc);
	//通讯录已满
	if (pc->sz == MAX)
	{
		printf("通讯录已满,无法添加!\n");
		Sleep(2000);
		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].tele);
	printf("请输入联系人住址:> ");
	scanf("%s", pc->data[pc->sz].addr);
	pc->sz++;

	printf("添加成功!\n");
	Sleep(1000);
}

//显示联系人
void ShowContact(const Contact* pc)
{
	assert(pc);

	printf("%-s\t%-s\t%-5s\t%-15s\t%-20s\n", "姓名", "年龄", "性别", "电话", "住址");
	for (int i = 0; i < pc->sz; i++)
	{
		printf("%-s\t%-d\t%-5s\t%-15s\t%-20s\n",
			pc->data[i].name,
			pc->data[i].age,
			pc->data[i].sex,
			pc->data[i].tele,
			pc->data[i].addr
		);
	}
}


//查找要删除的人并返回下标
int FindContact(const Contact* pc, const char* name)
{
	for (int i = 0; i < pc->sz; i++)
	{
		if (strcmp(pc->data[i].name, name) == 0)
		{
			return i;//找到了
		}
	}

	return -1;//没找到
}

//删除联系人
void DelContact(Contact* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空,无法删除!\n");
		Sleep(2000);
		return;
	}

	char name[NAME_MAX] = { 0 };
	printf("请输入要删除人的姓名:> ");
	scanf("%s", name);

	int pos = FindContact(pc, name);

	if (pos != -1)
	{
		//删除
		for (int i = pos; i < pc->sz - 1; i++)
		{
			pc->data[i] = pc->data[i + 1];
		}

		pc->sz--;
		printf("成功删除联系人!\n");
		Sleep(1000);
	}
	else
	{
		printf("没有此联系人!\n");
		Sleep(2000);
	}
}



//显示单个联系人信息
void Print(const Contact* pc, int pos)
{
	assert(pc);

	printf("%-s\t%-s\t%-5s\t%-15s\t%-20s\n", "姓名", "年龄", "性别", "电话", "住址");

	printf("%-s\t%-d\t%-5s\t%-15s\t%-20s\n",
		pc->data[pos].name,
		pc->data[pos].age,
		pc->data[pos].sex,
		pc->data[pos].tele,
		pc->data[pos].addr);

}

//查找指定联系人
void Search(const Contact* pc)
{
	assert(pc);

	char name[NAME_MAX] = { 0 };
	printf("请输入要查找联系人姓名:> ");
	scanf("%s", name);

	int pos = FindContact(pc, name);
	if (pos != -1)
	{
		Print(pc, pos);
	}
	else
	{
		printf("没有此联系人!\n");
		Sleep(2000);
		system("cls");
	}
}


//修改联系人信息菜单
void menu1()
{
	system("cls");
	printf("*****************************************\n");
	printf("********* 1. name     2. age   **********\n");
	printf("********* 3. sex      4. tele  **********\n");
	printf("********* 5. addr     6. all   **********\n");
	printf("********* 0. exit              **********\n");
	printf("*****************************************\n");
}

//修改名字
void ModName(Contact* pc, int ret)
{
	assert(pc);

	printf("请输入修改后联系人姓名:> ");
	scanf("%s", pc->data[ret].name);
}

//修改年龄
void ModAge(Contact* pc, int ret)
{
	assert(pc);

	printf("请输入修改后联系人年龄:> ");
	scanf("%d", &pc->data[ret].age);
}

//修改性别
void ModSex(Contact* pc, int ret)
{
	assert(pc);

	printf("请输入修改后联系人性别:> ");
	scanf("%s", &pc->data[ret].sex);
}

//修改电话
void ModTele(Contact* pc, int ret)
{
	assert(pc);

	printf("请输入修改后联系人电话:> ");
	scanf("%s", &pc->data[ret].tele);
}

//修改住址
void ModAddr(Contact* pc, int ret)
{
	assert(pc);

	printf("请输入修改后联系人住址:> ");
	scanf("%s", &pc->data[ret].addr);
}


void ModAll(Contact* pc, int ret)
{
	assert(pc);

	printf("请输入联系人姓名:> ");
	scanf("%s", pc->data[ret].name);
	printf("请输入联系人年龄:> ");
	scanf("%d", &pc->data[ret].age);
	printf("请输入联系人性别:> ");
	scanf("%s", pc->data[ret].sex);
	printf("请输入联系人电话:> ");
	scanf("%s", pc->data[ret].tele);
	printf("请输入联系人住址:> ");
	scanf("%s", pc->data[ret].addr);
}


//修改联系人
void ModContact(Contact* pc)
{
	assert(pc);
	//判断是否为空
	if (pc->sz == 0)
	{
		printf("通讯录为空,无法修改!\n");
		Sleep(2000);
		system("cls");
		return;
	}

	char name[NAME_MAX] = { 0 };
	printf("请输入要修改系人姓名:> ");
	scanf("%s", name);
	//判断是否有该联系人
	int ret = FindContact(pc, name);
	
	//有该联系人
	if (ret != -1)
	{
		int n = 0;
		do
		{
			menu1();
			Print(pc, ret);
			printf("请选择修改内容:> ");
			scanf("%d", &n);
			//修改
			switch (n)
			{
			case 1:
				ModName(pc,ret);
				break;
			case 2:
				ModAge(pc, ret);
				break;
			case 3:
				ModSex(pc, ret);
				break;
			case 4:
				ModTele(pc, ret);
				break;
			case 5:
				ModAddr(pc, ret);
				break;
			case 6:
				ModAll(pc, ret);
				break;
			case 0:
				printf("修改结束!\n");
				Sleep(2000);
				system("cls");
				break;
			default:
				printf("选择数非法!\n");
				Sleep(2000);
				system("cls");
				break;
			}

		} while (n);
	}
	else
	{
		printf("没有此联系人!\n");
		Sleep(2000);
		system("cls");
	}
}

//排序菜单
void menu2()
{
	system("cls");
	printf("**********************************\n");
	printf("***** 1. name    2. age **********\n");
	printf("**********************************\n");
}

//名字比较函数
int cmp_name(const void* str1, const void* str2)
{
	//return strcmp(((PeoInfo*)str1)->name, ((PeoInfo*)str2)->name);
	return strcmp((((Contact*)str1)->data)->name, (((Contact*)str2)->data)->name);
}

//名字排序
void SortName(Contact* pc)
{
	qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_name);
}

//年龄比较函数
int cmp_age(const void* str1, const void* str2)
{

	//return ((PeoInfo*)str1)->age - ((PeoInfo*)str2)->age;
	return (((Contact*)str1)->data)->age - (((Contact*)str2)->data)->age;
}
//年龄排序
void SortAge(Contact* pc)
{
	qsort(pc->data, pc->sz, sizeof(pc->data[0]), cmp_age);
}

//排序联系人信息
void SortContact(Contact* pc)
{
	assert(pc);
	//判断为空
	if (pc->sz == 0)
	{
		printf("通讯录为空,无法排序!\n");
		Sleep(3000);
		system("cls");
		return;
	}


	menu2();
	int n = 0;
	printf("请选择排序方式:> ");
	scanf("%d", &n);
	//排序
	switch (n)
	{
	case 1:
		SortName(pc);
		system("cls");
		printf("排序成功!\n");
		break;
	case 2:
		SortAge(pc);
		system("cls");
		printf("排序成功!\n");
		break;
	default:
		printf("选择数非法!\n");
		Sleep(3000);
		system("cls");
		break;
	}
}

test.c

#include"contact.h"

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");
}

void test()
{
	int input = 0;
	Contact con;
	InitContact(&con);
	do
	{
		menu();
		printf("请选择操作数:> ");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			AddContact(&con);
			system("cls");
			break;
		case 2:
			DelContact(&con);
			system("cls"); 
			break;
		case 3:
			system("cls");
			Search(&con);
			break;
		case 4:
			ModContact(&con);
			break;
		case 5:
			system("cls");
			ShowContact(&con);
			break;
		case 6:
			SortContact(&con);
			break;
		case 0:
			printf("退出成功!\n");
			break;
		default:
			printf("选择数非法!\n");
			break;
		}

	} while (input);
}

int main()
{
	test();
	return 0;
}

OK,本期分享就到这里!好兄弟,我们下期再见!

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

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

相关文章

docker学习(十五)docker安装MongoDB

什么是MongoDB? MongoDB 是一个开源的、面向文档的 NoSQL 数据库管理系统&#xff0c;它以高性能、灵活的数据存储方式而闻名。与传统的关系型数据库不同&#xff0c;MongoDB 采用了一种称为 BSON&#xff08;Binary JSON&#xff09;的二进制 JSON 格式来存储数据。它是一种非…

【AIGC 讯飞星火 | 百度AI|ChatGPT| 】智能对比

AI智能对比 &#x1f378; 前言&#x1f37a; 概念类对比&#x1f375; 讯飞&#x1f375; 百度AI&#x1f375; chatGPT &#x1f379; 功能类对比☕ 讯飞☕ 百度AI☕ chatGPT &#x1f943; 可输入字数对比&#x1f964; 百度AI&#x1f964; 讯飞&#x1f964; chatGPT &…

markdown编写微信公众号文章

微信公众号文章编写&#xff0c;暂不支持MarkDown的使用&#xff0c; 推荐工具&#xff1a; 墨滴 全称叫做&#xff1a; Makedown Nice&#xff0c;后面会以mdNice代替使用。 通过官网的写文章&#xff0c;支持在线编译安装chrome浏览器插件&#xff0c; 支持在微信公众号编译…

字符串旋转(1)

目录 ​编辑 题目要求&#x1f60d;&#xff1a; 题目内容❤&#xff1a; 题目分析&#x1f4da;&#xff1a; 主函数部分&#x1f4d5;&#xff1a;​编辑 方法一&#x1f412;&#xff1a; 方法二&#x1f412;&#x1f412;&#xff1a; 方法三&#x1f412;&#x1f…

Day978.如何在移动App中使用OAuth 2.0? -OAuth 2.0

如何在移动App中使用OAuth 2.0&#xff1f; Hi&#xff0c;我是阿昌&#xff0c;今天学习记录的是关于如何在移动App中使用OAuth 2.0&#xff1f;的内容。 除了 Web 应用外&#xff0c;现实环境中还有非常多的移动 App。 那么&#xff0c;在移动 App 中&#xff0c;能不能使…

手把手带你设计接口自动化测试用例(一):提取接口信息并分析

1、测试行业市场现状 随着市场需求的变化&#xff0c;大部分企业在招聘测试人员时&#xff0c;都会提出接口自动化测试的相关要求&#xff0c;为什么会这样呢&#xff1f; 目前&#xff0c;软件构架基本上都是前后端分离的&#xff0c;软件的主要功能由服务端提供。从整个软件…

生成国密SM2密钥对

在线生成国密密钥对 生成的密钥对要妥善保管&#xff0c;丢失是无法找回的。

windows无法与设备或主DNS服务器通信

今天电脑连上wifi后发现qq可以登录,爱奇艺也可以正常使用,但是就浏览器不能用,不管哪个网站都是无法访问,点击下面的Windows网络诊断后发现是因为windows无法与设备或主DNS服务器通信 1.右下角右键wifi图标,打开网络和internet设置 2.点击网络和共享中心 3. 点击更改适配器设置…

(杭电多校)2023“钉耙编程”中国大学生算法设计超级联赛(9)

1002 shortest path 记忆化搜索可以用 map 实现&#xff0c;频繁读取而不考虑元素顺序的可以使用 unordered_map &#xff0c;有效降低时间空间复杂度 dfs(n/2)n%21,其中n%2表示将n变为偶数的次数,1表示操作n/2,dfs(n/2)即表示将n/2变为1的次数 AC代码: #include<iostre…

深入探索Spring后置处理器:解析作用与实际应用场景

前言 BeanDefinitionRegistryPostProcessor &#xff0c; BeanFactoryPostProcessor &#xff0c;InstantiationAwareBeanPostProcessor&#xff0c; BeanPostProcessor是spring生命周期中常见的4个后置处理器&#xff0c;但是对于其作用和执行顺序很多人还不是非常清楚&#…

软件测试的调用接口怎么调用,逻辑是什么?

一、什么是接口测试&#xff1f; 接口测试是测试系统组件之间接口的测试。接口主要用于检测外部系统和内部子系统之间的交互点。测试的重点是检查数据交换、传输、控制和管理过程&#xff0c;以及系统之间的相互逻辑依赖。 二、为什么要做接口测试&#xff1f; 在淘宝系统的…

Java8新特性---Stream流

什么是Stream 是数据渠道&#xff0c;用于操作数据源&#xff08;集合、数组等&#xff09;所生成的元素序列。集合讲究的是数据&#xff0c;流讲的是计算 注意&#xff1a; Stream不会自己存储元素Stream不会改变源对象&#xff0c;相反&#xff0c;他们会返回持有结果的新…

GPT-4耗尽全宇宙数据!OpenAI接连吃官司,竟因数据太缺了,UC伯克利教授发出警告

穷尽「全网」&#xff0c;生成式AI很快无数据可用。 近日&#xff0c;著名UC伯克利计算机科学家Stuart Russell称&#xff0c;ChatGPT和其他AI工具的训练可能很快耗尽「全宇宙的文本」。 换句话说&#xff0c;训练像ChatGPT这样的AI&#xff0c;将因数据量不够而受阻。 这可能…

五、修改官方FreeRTOS例程(STM32F1)

1、官方源码下载 (1)进入FreeRTOS官网&#xff1a;FreeRTOS官网 (2)下载FreeRTOS。(选择带示例的下载) 2、删减目录 (1)下载后解压的FreeRTOS文件如下图所示。 (2)删除下图中红框勾选的文件。 FreeRTOS-Plus&#xff0c;FreeRTOS的生态文件&#xff0c;非必需的。tools&…

esp8266+电压检测模块检测电池电压

该模块5v时输出1v&#xff0c;因esp8266 ADC引脚(A0)支持电压范围是0v-1v&#xff0c;所以该方案仅支持0-5v电压检测 接线&#xff1a; - 接 esp8266GND 可不接 S 接 ADC esp8266 为 A0 VCC 被检测直流电 GND 被检测直流电- #include <Wire.h>const int adcPin A0; // …

Redis五大基本数据类型及其使用场景

文章目录 **一 什么是NoSQL&#xff1f;****二 redis是什么&#xff1f;****三 redis五大基本类型**1 String&#xff08;字符串&#xff09;**应用场景** 2 List&#xff08;列表&#xff09;**应用场景** 3 Set&#xff08;集合&#xff09;4 sorted set&#xff08;有序集合…

excel逻辑函数篇1

1、AND(logical1,[logical2],…)&#xff1a;用于测试所有条件是否均为TRUE 检查所有参数均为true&#xff0c;如果是则返回true 2、OR(logical1,[logical2],…)&#xff1a;用于测试是否有为TRUE的条件 如果任意参数值为true&#xff0c;即返回true&#xff1b;只有当所有参数…

223、仿真-基于51单片机温湿度PH值二氧化碳(C02)报警Proteus仿真设计(程序+Proteus仿真+配套资料等)

毕设帮助、开题指导、技术解答(有偿)见文未 目录 一、硬件设计 二、设计功能 三、Proteus仿真图 四、程序源码 资料包括&#xff1a; 需要完整的资料可以点击下面的名片加下我&#xff0c;找我要资源压缩包的百度网盘下载地址及提取码。 方案选择 单片机的选择 方案一&…

机器学习笔记 - 基于keras + 小型Xception网络进行图像分类

一、简述 Xception 是深度为 71 层的卷积神经网络,仅依赖于深度可分离的卷积层。 论文中将卷积神经网络中的 Inception 模块解释为常规卷积和深度可分离卷积运算(深度卷积后跟点卷积)之间的中间步骤。从这个角度来看,深度可分离卷积可以理解为具有最大数量塔的 Inception 模…

学习笔记230804---restful风格的接口,delete的传参方式问题

如果后端提供的删除接口是restful风格&#xff0c;那么使用地址栏拼接的方式发送请求&#xff0c;数据放在主体中&#xff0c;后端接受不到&#xff0c;当然也还有一种可能&#xff0c;后端在这个接口的接参设置上是req.query接参。 问题描述 今天遇到的问题是&#xff0c;de…