用C实现通讯录(详细讲解+源码)

news2024/11/19 21:26:10

 前言

📚作者简介:爱编程的小马,正在学习C/C++,Linux及MySQL..

📚以后会将数据结构收录为一个系列,敬请期待

● 本期内容会给大家带来通讯录的讲解,主要是利用结构体来实现通讯录,该通讯录可以存储几百人甚至是几千人的信息,每个信息包括:姓名,年龄,性别,电话以及地址。准备好了就跟着小马出发吧。


通讯录

 前言

1.通讯录环境及文件配置

2.通讯录的实现

2.1 通讯录的功能

2.2 通讯录的定义

2.3 录入人员信息的函数实现

2.4 定义检查人员是否存在函数

 2.5 删除通讯录中已经存在的信息函数实现

 2.6 查找通讯录成员函数

2.7 修改通讯录成员函数

2.8 显示通讯录

2.9 给通讯录排序

3.通讯录全部源码

3.1 test.c

3.2 contact.h

3.3 contact.c

总结


 

1. 通讯录环境及文件配置

本通讯录是在VS2019的环境下,需要创建三个文件,test.c ,contact.c ,contact.h

test.c //主函数,调用通讯录相关功能

contact.c //函数功能的实现

contact.h //函数头文件的包含及函数的声明

2. 通讯录的实现

2.1 通讯录的功能

2.2 通讯录的定义

首先需要一个菜单,可以提供给玩家选择:

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

 通讯录的定义:

1、封装一个结构体信息用来存储人员信息

2、再需要一个结构体数组来管理这个人员信息(暂时能存储100个人)


#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 20
#define ADDR_MAX 30
#define ADD_ONCE 2
#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;

2.3 录入人员信息的函数实现

1、判断:如果人员信息录入满了就不再录入了

2、挨个录入姓名,年龄,性别,电话以及住址,录入完成后打印增加成功,然后记录人员信息的sz往后走一步(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");
}

2.4 定义检查人员是否存在函数

为什么要定义这个函数呢?因为两点原因:1、后面的删除,查找,修改人员信息是不是都要先确定这个人是否存在我们再进行下一步操作。2、在前面定义,后面直接引用即可,不用反复定义


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

 2.5 删除通讯录中已经存在的信息函数实现

1、判断:如果通讯录为空,就不要删除了,直接返回

2、如果不为空,我们就调用检查人员是否存在这个函数,如果存在,则继续,如果不存在,就返回

3、如果有这个人,那应该从这个人的地址往后,依次向前覆盖,最后总数sz-1是不是就完成了删除

void DelContact(contact* pc)
{
	char name[NAME_MAX];
	printf("请输入要删除人的名字:>");
	scanf("%s", name);
	if (pc->sz == 0)
	{
		printf("通讯录为空,无法删除\n");
		return;
	}
	int ret = FindName(pc, name);
	if (ret == -1)
	{
		printf("查无此人,无法删除请重试\n");
		return;
	}
	int i = 0;
	for (i = ret; i < ret - 1; i++)
	{
		pc->data[i] = pc->data[i + 1];
	}
	pc->sz--;
	printf("删除成功\n");
}

 2.6 查找通讯录成员函数

1、判断:如果通讯录为空,不要查找了直接返回

2、调用检查人员存在函数,如果没有就直接返回,如果存在就直接打印人员信息

void SearchContact(contact* pc)
{
	char name[NAME_MAX];
	int i = 0;
	printf("请输入被查找人的名字:>");
	scanf("%s", name);
	int ret = FindName(pc, name);
	if (ret == -1)
	{
		printf("查无此人\n");
	}
	else
	{
		printf("%-20s%-5s%-5s%-12s%-20s\n", "姓名", "年龄", "性别", "电话", "地址");
		printf("%-20s%-5d%-5s%-12s%-20s\n", pc->data[ret].name,
			pc->data[ret].age,
			pc->data[ret].sex,
			pc->data[ret].tele,
			pc->data[ret].addr);
	}
}

2.7 修改通讯录成员函数

1、判断:如果通讯录为空就不要修改了,直接返回

2、调用检查人员存在函数,如果没有就直接返回,如果存在就直接修改人员信息

void ModifyContact(contact* pc)
{
	char name[NAME_MAX];
	int i = 0;
	printf("请输入要修改人的名字:>");
	scanf("%s", name);
	int ret = FindName(pc, name);
	if (ret == -1)
		printf("要修改的人不存在\n");
	else
	{
		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");
	}
	
}

2.8 显示通讯录

void ShowContact(contact* pc)
{
	assert(pc);
	if (pc->sz == 0)
		printf("通讯录为空,无需打印\n");
	else
	{
		int i = 0;
		for (i = 0; i < pc->sz; i++)
		{
			printf("%-20s%-5s%-5s%-12s%-20s\n", "姓名", "年龄", "性别", "电话", "地址");
			printf("%-20s%-5d%-5s%-12s%-20s\n", pc->data[i].name,
										 pc->data[i].age,
										 pc->data[i].sex,
										 pc->data[i].tele,
										 pc->data[i].addr);
		}
	}
}

2.9 给通讯录排序

1、首先需要确定按什么排序

2、实现的思想是使用qsort函数

void menun()
{
	printf("******************************\n");
	printf("**** 1.按名字    2.按年龄 ****\n");
	printf("**** 3.按性别    4.按电话 ****\n");
	printf("**** 5.按地址             ****\n");
	printf("******************************\n");
}
int NAME(const void* p1, const void* p2)
{
	return strcmp(((peoinfo*)p1)->name, ((peoinfo*)p2)->name);
}

int AGE(const void* p1, const void* p2)
{
	return (((peoinfo*)p1)->age- ((peoinfo*)p2)->age);
}
int SEX(const void* p1, const void* p2)
{
	return strcmp(((peoinfo*)p1)->sex, ((peoinfo*)p2)->sex);
}
int TELE(const void* p1, const void* p2)
{
	return strcmp(((peoinfo*)p1)->tele, ((peoinfo*)p2)->tele);
}
int ADDR(const void* p1, const void* p2)
{
	return strcmp(((peoinfo*)p1)->addr, ((peoinfo*)p2)->addr);
}
void SortContact(contact* pc)
{
	menun();
	int input = 0;
	printf("请输入排序的方式:>");
	scanf("%d", &input);
	int (*cmp[6])(const void* p1, const void* p2) = { NULL,NAME,AGE,SEX,TELE,ADDR};
	switch (input)
	{
	case 1:
		qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);
		break;
	case 2:
		qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);
		break;
	case 3:
		qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);
		break;
	case 4:
		qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);
		break;
	case 5:
		qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);
		break;
	default:
		printf("输入非法\n");
	}
	printf("排序成功\n");
}

3. 通讯录全部源码

3.1 test.c

#define  _CRT_SECURE_NO_WARNINGS 1
#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");


}
enum Option
{
	EXIT,
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SHOW,
	SORT
};
int main()
{
	int input = 0;
	contact con;
	Init(&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:
			SortContact(&con);
			break;
		case EXIT:
			{
			printf("退出程序\n");
			break;
			}
			
		default:
			printf("非法输入,请重新输入\n");
		}
	} while (input);
	return 0;
}

3.2 contact.h

#pragma once
#include<stdio.h>
#include<assert.h>
#include<string.h>
#include<stdlib.h>

#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 20
#define ADDR_MAX 30
#define ADD_ONCE 2
#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 Init(contact * pc);
void  AddContact(contact* pc);

void ShowContact(contact*pc);

void DelContact(contact* pc);


void SearchContact(contact *pc);

void ModifyContact(contact* pc);


void SortContact(contact* pc);

void free_contact(contact *pc);

3.3 contact.c

#define  _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"

void Init(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].tele);
	printf("请输入地址:>");
	scanf("%s", pc->data[pc->sz].addr);
	pc->sz++;
	printf("添加成功\n");
}

void ShowContact(contact* pc)
{
	assert(pc);
	if (pc->sz == 0)
		printf("通讯录为空,无需打印\n");
	else
	{
		int i = 0;
		for (i = 0; i < pc->sz; i++)
		{
			printf("%-20s%-5s%-5s%-12s%-20s\n", "姓名", "年龄", "性别", "电话", "地址");
			printf("%-20s%-5d%-5s%-12s%-20s\n", pc->data[i].name,
										 pc->data[i].age,
										 pc->data[i].sex,
										 pc->data[i].tele,
										 pc->data[i].addr);
		}
	}
}

//从后往前覆盖就好了,总数删除完毕之后再减一个


int FindName(contact* pc,char name[])
{
	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)
{
	char name[NAME_MAX];
	printf("请输入要删除人的名字:>");
	scanf("%s", name);
	if (pc->sz == 0)
	{
		printf("通讯录为空,无法删除\n");
		return;
	}
	int ret = FindName(pc, name);
	if (ret == -1)
	{
		printf("查无此人,无法删除请重试\n");
		return;
	}
	int i = 0;
	for (i = ret; i < ret - 1; i++)
	{
		pc->data[i] = pc->data[i + 1];
	}
	pc->sz--;
	printf("删除成功\n");
}


void SearchContact(contact* pc)
{
	char name[NAME_MAX];
	int i = 0;
	printf("请输入被查找人的名字:>");
	scanf("%s", name);
	int ret = FindName(pc, name);
	if (ret == -1)
	{
		printf("查无此人\n");
	}
	else
	{
		printf("%-20s%-5s%-5s%-12s%-20s\n", "姓名", "年龄", "性别", "电话", "地址");
		printf("%-20s%-5d%-5s%-12s%-20s\n", pc->data[ret].name,
			pc->data[ret].age,
			pc->data[ret].sex,
			pc->data[ret].tele,
			pc->data[ret].addr);
	}
}


void ModifyContact(contact* pc)
{
	char name[NAME_MAX];
	int i = 0;
	printf("请输入要修改人的名字:>");
	scanf("%s", name);
	int ret = FindName(pc, name);
	if (ret == -1)
		printf("要修改的人不存在\n");
	else
	{
		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 menun()
{
	printf("******************************\n");
	printf("**** 1.按名字    2.按年龄 ****\n");
	printf("**** 3.按性别    4.按电话 ****\n");
	printf("**** 5.按地址             ****\n");
	printf("******************************\n");
}
int NAME(const void* p1, const void* p2)
{
	return strcmp(((peoinfo*)p1)->name, ((peoinfo*)p2)->name);
}

int AGE(const void* p1, const void* p2)
{
	return (((peoinfo*)p1)->age- ((peoinfo*)p2)->age);
}
int SEX(const void* p1, const void* p2)
{
	return strcmp(((peoinfo*)p1)->sex, ((peoinfo*)p2)->sex);
}
int TELE(const void* p1, const void* p2)
{
	return strcmp(((peoinfo*)p1)->tele, ((peoinfo*)p2)->tele);
}
int ADDR(const void* p1, const void* p2)
{
	return strcmp(((peoinfo*)p1)->addr, ((peoinfo*)p2)->addr);
}
void SortContact(contact* pc)
{
	menun();
	int input = 0;
	printf("请输入排序的方式:>");
	scanf("%d", &input);
	int (*cmp[6])(const void* p1, const void* p2) = { NULL,NAME,AGE,SEX,TELE,ADDR};
	switch (input)
	{
	case 1:
		qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);
		break;
	case 2:
		qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);
		break;
	case 3:
		qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);
		break;
	case 4:
		qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);
		break;
	case 5:
		qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);
		break;
	default:
		printf("输入非法\n");
	}
	printf("排序成功\n");
}

总结

上文就是通讯录的详细讲解和全部源码,下一节会给大家更新动态内存存储相关的知识。

如果这份博客对大家有帮助,希望各位给小马一个大大的点赞鼓励一下,如果喜欢,请收藏一下,谢谢大家!!!
制作不易,如果大家有什么疑问或给小马的意见,欢迎评论区留言。

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

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

相关文章

【微信小程序调用百度API实现图像识别实战】-前后端加强版

前言&#xff1a;基于前面两篇图像识别项目实战文章进行了改造升级。 第一篇 入门【微信小程序调用百度API实现图像识别功能】----项目实战 第二篇 前后端结合 【微信小程序调用百度API实现图像识别实战】----前后端分离 这一篇主要讲述的是在第二篇的基础上新增意见反馈功能&a…

【35分钟掌握金融风控策略13】单维度策略监控和调优

目录 单维度策略监控和调优 策略宏观监控和调优 项目运营报表 资产监控报表 客群质量监控报表 资产使用报表 项目风险报表 FSTPD逾期报表 迁徙率报表 Vintage报表 贷后催收报表 单维度策略监控和调优 若贷前授信审批环节上线的是基于决策树开发的多维度策略&#x…

html+css 选择器优先级

1.基本选择器优先级 id>class>tagname(标签选择器)>*(通配符选择器) <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>基本选择器的优先级</title><style type"text/css"…

微信小程序使用echarts实现条形统计图功能

微信小程序使用echarts组件实现条形统计图功能 使用echarts实现在微信小程序中统计图的功能&#xff0c;其实很简单&#xff0c;只需要简单的两步就可以实现啦&#xff0c;具体思路如下&#xff1a; 引入echarts组件调用相应的函数方法 由于需要引入echarts组件&#xff0c;代…

永磁同步电机PMSM负载状态估计simulink模型

永磁同步电机PMSM负载状态估计simulink模型&#xff0c;龙伯格观测器&#xff0c;各种卡尔曼滤波器&#xff0c;矢量控制&#xff0c;坐标变换&#xff0c;永磁同步电机负载转矩估计&#xff0c;pmsm负载转矩测量&#xff0c;负载预测&#xff0c;转矩预测的matlab/simulink仿真…

锂电池SOH预测 | 基于LSTM的锂电池SOH预测(附matlab完整源码)

锂电池SOH预测 锂电池SOH预测完整代码锂电池SOH预测 锂电池的SOH(状态健康度)预测是一项重要的任务,它可以帮助确定电池的健康状况和剩余寿命,从而优化电池的使用和维护策略。 SOH预测可以通过多种方法实现,其中一些常用的方法包括: 容量衰减法:通过监测电池的容量衰减…

BPE、Wordpiece、Unigram、SpanBERT等Tokenizer细节总结

BPE(Byte Pair Encoding) GPT-2和Roberta用的是这种&#xff0c;不会产生[UNK]这个unknown字符 这部分部分摘录自https://martinlwx.github.io/zh-cn/the-bpe-tokenizer/ 看以下code例子就足够理解了&#xff0c;核心是维护self.merges&#xff08;维护一个pair->str的字…

基于数据挖掘的斗鱼直播数据可视化分析系统

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长 QQ 名片 :) 1. 项目简介 随着网络直播平台的兴起&#xff0c;斗鱼直播作为其中的佼佼者&#xff0c;吸引了大量用户和观众。为了更好地理解和分析斗鱼直播中的数据&#xff0c;本项目介绍了一个基于数据挖掘的斗鱼直播数据…

无人机GB42590接收端 +接收端模组,同时支持2.4G与5.8G双频

严格按照GB42590的协议开发的发射端&#xff0c;通过串口和模块通讯&#xff0c;默认波特率 921600。 http://www.doit.am/深圳四博智联科技有限公司https://shenzhendoit.taobao.com/category-1734422372.htm?spma1z10.1-c-s.0.0.560c74d77eT01G&searchy&catNameGB4…

MySQL数据库安装——zip压缩包形式

安装压缩包zip形式的 MySQL 8数据库 一 、先进入官网下载 https://dev.mysql.com/downloads/mysql/ 二、解压到某个文件夹 我解压到了D:\mysql\mysql8 下面 然后在这个文件夹下手动创建 my.ini 文件和 data 文件夹 my.ini 内容如下&#xff1a; 注意 basedir 和 datadi…

Docker数据管理、网络通信和Dockerfile

一.数据管理 数据卷是一个供容器使用的特殊目录&#xff0c;位于容器中。可将宿主机的目录挂载到数据卷上&#xff0c;对数据卷的修改操作立刻可见&#xff0c;并且更新数据不会影响镜像&#xff0c;从而实现数据在宿主机与容器之间的迁移。数据卷的使用类似于 Linux 下对目录…

面试算法题精讲:最长回文子串

面试算法题精讲&#xff1a;最长回文子串 题目来源&#xff1a;5. 最长回文子串 题目描述&#xff1a; 给你一个字符串 s&#xff0c;找到 s 中最长的回文子串。 如果字符串的反序与原始字符串相同&#xff0c;则该字符串称为回文字符串。 解法1&#xff1a;动态规划 对于…

ubuntu22.04安装TensorRT(过程记录)

重要说明&#xff1a;此贴经过多次修改。第一次安装的的为trt8.6.1版本。第二次安装的10.0.0.6版本。有些地方可能没改过来&#xff0c;比如链接向导&#xff0c;我懒得改了&#xff0c;但是流程是对的。 cuda和cudnn版本对应关系 tensorRT历史发行版本 CUDA历史发行版本 cudn…

【Godot4.2】有序和无序列表函数库 - myList

概述 在打印输出或其他地方可能需要构建有序或无序列表。本质就是构造和维护一个纯文本数组。并用格式化文本形式&#xff0c;输出带序号或前缀字符的多行文本。 为此我专门设计了一个类myList&#xff0c;来完成这项任务。 代码 以下是myList类的完整代码&#xff1a; # …

Android 设置头像 - 相册拍照

Android开发在个人信息管理中&#xff0c;如果设置头像&#xff0c;一般都提供了从相册选择和拍照两种方式。下午将针对设置用户头像相册和拍照两种方式的具体实现进行详细说明。 在实际实现过程中需要使用到权限管理&#xff0c;新版本的Android需要动态申请权限&#xff0c;权…

【JAVA】一文掌握Java并发编程

Java 开发中&#xff0c;并发编程属于相当重要的一个知识点&#xff0c;可以说&#xff0c;Java 的并发能力&#xff0c;是成就今日 Java 地位的因素之一。Java 的并发编程由浅入深实质上是包含 Java&#xff08;API&#xff09;层、JVM&#xff08;虚拟机&#xff09;层、内核…

Mac下使用homebrew管理多版本mysql同时启动

Mac下使用homebrew管理多版本mysql同时启动 思路 给每个版本分配不同的数据目录和配置文件即可 本文尝试了使用 brew 安装管理多个MySQL版本&#xff0c;同时运行、直接切换 安装 如果已有数据文件请自行备份以及使用 安装 mysql 5.7 brew install mysql5.7在 /opt/home…

运维笔记:基于阿里云跨地域服务器通信(上)

运维笔记 阿里云&#xff1a;跨地域服务器通信&#xff08;上&#xff09; - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this a…

C语言编译的优化等级应该选哪个?O0、O1、O2还是O3

在使用IDE开发STM32程序时&#xff0c;IDE一般都会提供优化等级设置的选项&#xff0c;例如下图中KEIL软件优化等级的设置。 从上图中也可以看出&#xff0c;设置不同的优化等级&#xff0c;实际上是修改了编译器的编译参数。这个编译器是由ARM公司提供的C/C编译器armclang或者…

opencv4.8 系列一环境搭搭建

open 运行环境&#xff1a; vs2017 下载地址&#xff1a;https://www.123pan.com/s/cVyRVv-ydPWh.html 一&#xff1a;新建项目 二&#xff1a;核心代码&#xff1a; 在这里插入代码片 #include<opencv2/opencv.hpp>int main(int argc,char** argv) {cv::Mat src cv…