通讯录实现【C语言】

目录

前言

一、整体逻辑分析

二、实现步骤

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.mfbz.cn/a/80631.html

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

相关文章

qsort函数详解

大家好&#xff0c;我是苏貝&#xff0c;本篇博客带大家了解qsort函数&#xff0c;如果你觉得我写的不错的话&#xff0c;可以给我一个赞&#x1f44d;吗&#xff0c;感谢❤️ 文章目录 一. qsort函数参数详解1.数组首元素地址base2.数组的元素个数num和元素所占内存空间大小w…

【数据结构OJ题】设计循环队列

原题链接&#xff1a;https://leetcode.cn/problems/design-circular-queue/ 1. 题目描述 2. 循环队列的概念和结构 为充分利用向量空间&#xff0c;克服"假溢出"现象的方法是&#xff1a;将向量空间想象为一个首尾相接的圆环&#xff0c;并称这种向量为循环向量。…

【100天精通python】Day41:python网络爬虫开发_爬虫基础入门

目录 专栏导读 1网络爬虫概述 1.1 工作原理 1.2 应用场景 1.3 爬虫策略 1.4 爬虫的挑战 2 网络爬虫开发 2.1 通用的网络爬虫基本流程 2.2 网络爬虫的常用技术 2.3 网络爬虫常用的第三方库 3 简单爬虫示例 专栏导读 专栏订阅地址&#xff1a;https://blog.csdn.net/…

OLED透明屏采购指南:如何选择高质量产品?

着科技的不断进步&#xff0c;OLED透明屏作为一种创新的显示技术&#xff0c;在各个行业中得到了广泛应用。 在进行OLED透明屏采购时&#xff0c;选择高质量的产品至关重要。在这篇文章中&#xff0c;尼伽将为您提供一个全面的OLED透明屏采购指南&#xff0c;帮助您了解关键步…

4.物联网LWIP之C/S编程

LWIP配置 服务器端实现 客户端实现 错误分析 一。LWIP配置&#xff08;FREERTOS配置&#xff0c;ETH配置&#xff0c;LWIP配置&#xff09; 1.FREERTOS配置 为什么要修改定时源为Tim1&#xff1f;不用systick&#xff1f; 原因&#xff1a;HAL库与FREERTOS都需要使用systi…

【力扣每日一题】2023.8.15 字符中的查找与替换

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 题目很长&#xff0c;简而言之就是检查字符串中对应索引的位置是否有特定的字符串&#xff0c;如果有&#xff0c;那么替换&#xff0c;返…

【Unity每日一记】关于五种范围检测方法的总结

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;uni…

==和equals方法之间的区别,hashcode的理解,String拼接,Spring拆分

==和equals方法之间的区别 字符串有字符串常量池的概念,本身就推荐使用String s="字符串", 这种形式来创建字符串对象, 而不是通过new关键字的方式, 因为可以把字符串缓存在字符串常量池中,方便下次使用,不用遇到new就在堆上开辟一块新的空间 有一对双胞胎姐妹,晓苑…

CVE-2015-5254漏洞复现

1.漏洞介绍。 Apache ActiveMQ 是美国阿帕奇&#xff08;Apache&#xff09;软件基金会所研发的一套开源的消息中间件&#xff0c;它支持 Java 消息服务&#xff0c;集群&#xff0c;Spring Framework 等。Apache ActiveMQ 5.13.0之前 5.x 版本中存在安全漏洞&#xff0c;该漏…

Java 集合详解

目录 1.集合体系结构 2.Collection集合 2.1 Collection集合 2.1.1 Collection基本方法 2.1.2 Collection遍历方式 2.1.2.1 迭代器遍历 2.1.2.2 增强for循环 2.1.2.3 Lambda表达式 3.List集合 3.1 List集合的基本方法 3.2 List集合的遍历方式 4.数据结构 4.1 数据结…

【C++11新特性】lambda表达式

文章目录 1. lambda表达式概念2. lambda表达式语法3. lambda表达式应用 1. lambda表达式概念 lambda表达式是一个匿名函数&#xff0c;恰当使用lambda表达式可以让代码变得简洁&#xff0c;并且可以提高代码的可读性。 见见lambda表达式的使用 现在要对若干商品分别按照价格和…

Maven之mirrorof范围

mirrorOf 是 central 还是 * 的问题 在配置阿里对官方中央仓库的镜像服务器时&#xff0c;我们使用到了 <mirror> 元素。 <mirror><id>aliyunmaven</id><mirrorOf>central</mirrorOf><name>阿里云公共仓库</name><url>…

File 类的用法, InputStream和Reader, OutputStream和Writer 的用法

前言 普通的文件长这样&#xff1a; 其实目录也是一种特殊文件&#xff1a; 一、文件前缀知识 &#xff08;一&#xff09;绝对路径和相对路径 以盘符开头的的路径&#xff0c;叫做绝对路径&#xff0c;如&#xff1a;D:\360Downloads\cat.jpg 以.或..开头的路径&#xff0c…

uni-app的Vue.js实现微信小程序的紧急事件登记页面功能

主要功能实现 完成发生时间选择功能&#xff0c;用户可以通过日期选择器选择事件发生的时间。实现事件类型选择功能&#xff0c;用户可以通过下拉选择框选择事件的类型。添加子养殖场编号输入框&#xff0c;用户可以输入与事件相关的子养殖场编号。完成事件描述输入功能&#…

PSP - 基于扩散生成模型预测蛋白质结构 EigenFold 算法与环境配置

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/132357976 Paper: EigenFold: Generative Protein Structure Prediction with Diffusion Models EigenFold 是用于蛋白质结构预测的扩散生成模型…

Python自动化实战之使用Selenium进行Web自动化详解

概要 为了完成一项重复的任务&#xff0c;你需要在网站上进行大量的点击和操作&#xff0c;每次都要浪费大量的时间和精力。Python的Selenium库就可以自动化完成这些任务。 在本篇文章中&#xff0c;我们将会介绍如何使用Python的Selenium库进行Web自动化&#xff0c;以及如何…

AlexNet阅读笔记

ImageNet classification with deep convolutional neural networks 原文链接&#xff1a;https://dl.acm.org/doi/abs/10.1145/3065386 中文翻译&#xff1a;https://blog.csdn.net/qq_38473254/article/details/132307508 使用深度卷积神经网络进行 ImageNet 分类 摘要 大…

【数据结构】如何用队列实现栈?图文详解(LeetCode)

LeetCode链接&#xff1a;225. 用队列实现栈 - 力扣&#xff08;LeetCode&#xff09; 本文默认读者已经掌握栈与队列的基本知识 或者先看我的另一篇博客&#xff1a;【数据结构】栈与队列_字节连结的博客-CSDN博客 做题思路 由于我们使用的是C语言&#xff0c;不能直接使用队…

ubuntu 部署 ChatGLM-6B 完整流程 模型量化 Nvidia

ubuntu 部署 ChatGLM-6B 完整流程 模型量化 Nvidia 初环境与设备环境准备克隆模型代码部署 ChatGLM-6B完整代码 ChatGLM-6B 是一个开源的、支持中英双语的对话语言模型&#xff0c;基于 General Language Model (GLM) 架构&#xff0c;具有 62 亿参数。结合模型量化技术&#x…

Python入门【装饰器​编辑、多个装饰器 、带参数的装饰器、生成器、 生成器定义、 迭代器】(二十八)

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱敲代码的小王&#xff0c;CSDN博客博主,Python小白 &#x1f4d5;系列专栏&#xff1a;python入门到实战、Python爬虫开发、Python办公自动化、Python数据分析、Python前后端开发 &#x1f4e7;如果文章知识点有错误…