当前位置: 首页 > news >正文

C语言之通讯录(动态 存储文件版)

目录

 前言

一.基本思路

 二.代码的实现

  2.1通讯录菜单

 2.2通讯录的定义及功能

 2.3函数实现 

 2.3.1初始化通讯录     

 2.3.2文件信息传递到通讯录里

 2.3.3扩容通讯录

 2.3.4增加联系人 

2.3.5删除联系人

2.3.6查询联系人

2.3.7修改联系人

2.3.8打印通讯录

2.3.9信息保留在文件中

 2.3.10销毁空间退出程序

三.完整代码

 3.1Text.c文件

3.2Contact.h文件

3.3Contact.c文件

总结


 前言

文件存储版的通讯录 是在通讯录的基础上添加了文件操作
在了解通讯录(文件存储版)之前,我们得好好学习一下  文件操作
只有掌握了操作文件,才能明白文件存储版的通讯录

一.基本思路

       1.通讯录是由多人的信息组合,信息:姓名,年龄,性别,地址等。

       2.通讯录的大小,存放的人数,此使用动态存储,更加方便存储和利用空间。

       3.通讯录的基本功能:增加联系人、删除联系人、查找联系人,修改联系人

       4.保存通讯录文档,方便下次使用。

   注:通讯录分三种:静态、动态、文件三种。而此文章讲述的是动态存储的文件版通讯录

           静态:大小固定,存储的人数有明确限制,无法改变,使用数组实现。

           动态:存储人数可以调节,可以随着人数的增加而增加,选择一个初始大小,之后可进行扩充操作,  可更好的利用空间。

           文件:该通讯录是在以上两种通讯录之一上加上存储文件的操作,在程序执行结束后都无法保存,录入的信息在程序结束时就会消失。为了保存录入的信息,可以通过文件操作来实现。

 二.代码的实现

  2.1通讯录菜单

                  菜单能够实现和用户的交互。需要选择增、删、查、改的功能。

                 所以,通讯录需要一个菜单。

                代码如下:

void menu()
{printf("*********************************\n");printf("*******1.添加        2.删除*******\n");printf("*******3.查找        4.修改*******\n");printf("*******5.显示        6.保存*******\n");printf("*******0.退出              *******\n");printf("*********************************\n");
}
//使用函数指针数组
void (*(p[7]))(Contact*) = { Exit,AddContact,DeleteContact,SearchContact,ModifyContact,PrintContact,SaveContact };int main()
{ //Contact cl;    这是下面代码结构体的//InitContact(&cl);int input;do {menu();printf("请输入->");scanf("%d", &input);if (input <= 6)p[input](&cl);  elseprintf("输入错误\n");}while (input != 0);
}

 为了方便,我们使用了函数指针数组,void (*(p[7]))(Contact*)   

 2.2通讯录的定义及功能

                    通讯录需要姓名、性别、年龄及电话,此时我们需要使用结构体来定义。还需要定义函数:增、删、查、改、打印学生信息、保存通讯录。

             代码如下:

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include<string.h>
typedef struct PeoInfo
{char name[10];//姓名int age;      //年龄char sex[3];  //性别int phone[12];//电话
}PeoInfo;typedef struct Contact
{	int size;  //当前存储的人数int capacity;  //通讯录容量大小contact* data;  //结构体指针,访问个人信息}Contact;
//初始化通讯录
void InitContact(Contact* pc);
//增加联系人
void AddContact(Contact* pc);
//删除联系人
void DeleteContact(Contact* pc);
//查找联系人
void SearchContact(Contact* pc);
//修改联系人
void ModifyContact(Contact* pc);
//显示通讯录
void PrintContact(Contact* pc);
//扩容通讯录
void CheckCapacity(Contact* pc);
//保存信息到文件
void SaveContact(Contact* pc);
//文件信息传递到通讯录
void LoadContact(Contact* pc);
//销毁空间,退出程序
void Exit(Contact* pc);

 2.3函数实现 

注:当通讯录退出的时候,把信息写到文件。
       当通讯录初始化后,加载文件的信息到通讯录中。

 2.3.1初始化通讯录     

              通讯录是动态的,所以需要扩容,给一定空间。


void InitContact(Contact* pc)
{// 此时通讯录是空的,应先为通讯录分配空间pc->data = (PeoInfo*)malloc(sizeof(PeoInfo) * 4);// 如果分配成功,将通讯录的size设为0,capacity设为初识大小pc->size = 0;pc->capacity = 4;//将文档的信息传递到动态内存里,函数实现在下方LoadContact(pc);
}

 2.3.2文件信息传递到通讯录里

将文件的信息加载到通讯录里

void LoadContact(Contact* pc)
{// 以读的形式打开文件FILE* pf = fopen("contact.txt", "rb");if (pf == NULL){perror("fopen");return;}// 将文件中的内容加载到通讯录中// 这里用fread函数,当fread函数读取的联系人信息数为0时,说明读取结束PeoInfo tmp = { 0 }; // 定义一个联系人信息的结构体,便于读取int i = 0;while (fread(&tmp, sizeof(PeoInfo), 1, pf)){CheckCapacity(pc); // 在这个函数中查看数组是否需要扩容,若需要,则扩容pc->data[i] = tmp;pc->size++;i++;}// 关闭文件fclose(pf);pf = NULL;return;
}

 2.3.3扩容通讯录

        添加联系人之前,需要判断通讯录是否满员,满员则需要扩容

void CheckCapacity(Contact* pc)
{// 判断通讯录是否已满,若满,进行扩容if (pc->size == pc->capacity){PeoInfo* tmp = (PeoInfo*)realloc(pc, sizeof(PeoInfo) * 4);if (tmp == NULL){printf("realloc fail\n");return;}pc->data = tmp;// 若扩容成功,增大capacitypc->capacity *= 2;}}

 2.3.4增加联系人 

            需要添加联系人的各项信息。

void AddContact(Contact* pc)
{int num = 0;printf("添加人数:");scanf("%d", &num);// 输入要添加的联系人的信息// 这里pc->data为结构体数组,pc->data[pc->size]为其中的元素,也就是某一个联系人的信息for (int i = 0; i < num; i++){//判断通讯录是否满人CheckCapacity(pc);printf("请输入名字\n");scanf("%s", pc->data[pc->size].name);printf("请输入性别\n");scanf("%s", pc->data[pc->size].sex);printf("请输入年龄\n");scanf("%d", &pc->data[pc->size].age);printf("请输入电话\n");scanf("%s", pc->data[pc->size].phone);pc->size++; // 将存入的联系人的数量加1}
}

2.3.5删除联系人

      需要找到该联系人的下标值,然后进行删除。


void DeleteContact(Contact* pc)
{int ret = 0;//记录寻找的下标值printf("请输入要删除的联系人的名字\n");char name[20];scanf("%s", name);// 定义一个新函数find,用来查找是否有这个联系人// 如果有,返回联系人的下标,如果没有,返回-1for (int i = 0; i < pc->size; i++){if (strcmp(pc->data[i].name, name) == 0){ret = i; break;}}if (ret){printf("不存在");}else {for (int i = ret; i < pc->size - 1; i++){pc->data[i] = pc->data[i + 1];}pc->size--;}}

2.3.6查询联系人

找到下标值,从而得到联系人的信息

void SearchContact(Contact* pc)
{int ret = 0;printf("请输入要查找的联系人的名字\n");char name[20];scanf("%s", name);// 利用已经定义的find函数进行查找for (int i = 0; i < pc->size; i++){if (strcmp(pc->data[i].name, name) == 0){ret = i; break;}}if (ret){printf("没有找到该联系人\n");}else{// 如果找到,打印该联系人的信息,首先打印五个标题printf("%-10s\t%-10s\t%-5s\t%-15s\n", "姓名", "性别", "年龄", "电话");printf("%-10s\t%-10s\t%-5d\t%-15s%\n",pc->data[ret].name,pc->data[ret].sex,pc->data[ret].age,pc->data[ret].phone);}}

2.3.7修改联系人

找到下标值,从而进行各项数据的修改

void ModifyContact(Contact* pc)
{int ret = 0;printf("请输入要查找的联系人的名字\n");char name[20];scanf("%s", name);for (int i = 0; i < pc->size; i++){if (strcmp(pc->data[i].name, name) == 0){ret = i; break;}}if (ret){printf("没有找到该联系人\n");}else{printf("请输入名字\n");scanf("%s", pc->data[ret].name);printf("请输入性别\n");scanf("%s", pc->data[ret].sex);printf("请输入年龄\n");scanf("%d", &pc->data[ret].age);printf("请输入电话\n");scanf("%s", pc->data[ret].phone);}}

2.3.8打印通讯录

打印每个人的具体数据

// 在这个函数内打印所有联系人的信息
void PrintContact(Contact* pc)
{// 首先打印五个标题printf("%-10s\t%-10s\t%-5s\t%-15s\n", "姓名", "性别", "年龄", "电话");// 然后用for循环打印所有联系人的信息for (int i = 0; i < pc->size; i++){printf("%-10s\t%-10s\t%-5d\t%-15s\n",pc->data[i].name,pc->data[i].sex,pc->data[i].age,pc->data[i].phone	);}
}

2.3.9信息保留在文件中

程序退出时,要将销毁空间,并且把数据存入文件里,方便下次调用

void SaveContact(Contact* pc)
{FILE* p = fopen("contact.txt", "wb");if (p == NULL){perror("SaveContact");}else {int i = 0;for (i; i < pc->size; i++){fwrite(pc->data + i, sizeof(PeoInfo), 1, p);}fclose(p);p = NULL;printf("保存成功");}}

 2.3.10销毁空间退出程序

void Exit(Contact* pc)
{//销毁空间free(pc->data);pc->data = NULL;pc->size = 0;pc->capacity = 0;
}

三.完整代码

和上面的代码比起来,连贯了Contact.c的各个函数实现。

 3.1Text.c文件

#include"Contact.h"
void menu()
{printf("*********************************\n");printf("*******1.添加        2.删除*******\n");printf("*******3.查找        4.修改*******\n");printf("*******5.显示        6.保存*******\n");printf("*******0.退出              *******\n");printf("*********************************\n");
}
//使用函数指针数组
void (*(p[7]))(Contact*) = { Exit,AddContact,DeleteContact,SearchContact,ModifyContact,PrintContact,SaveContact };int main()
{//定义结构体Contact cl;InitContact(&cl);int input;do {menu();printf("请输入->");scanf("%d", &input);if (input <= 6)p[input](&cl);elseprintf("输入错误\n");} while (input != 0);
}

3.2Contact.h文件

#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#include<string.h>
typedef struct PeoInfo
{char name[10];//姓名int age;      //年龄char sex[3];  //性别int phone[12];//电话
}PeoInfo;typedef struct Contact
{int size;  //当前存储的人数int capacity;  //通讯录容量大小PeoInfo* data;  //结构体指针,访问个人信息}Contact;
//初始化通讯录
void InitContact(Contact* pc);
//增加联系人
void AddContact(Contact* pc);
//删除联系人
void DeleteContact(Contact* pc);
//查找联系人
void SearchContact(Contact* pc);
//修改联系人
void ModifyContact(Contact* pc);
//显示通讯录
void PrintContact(Contact* pc);
//扩容通讯录
void CheckCapacity(Contact* pc);
//销毁并且保存通讯录
void SaveContact(Contact* pc);
void LoadContact(Contact* pc);
void Exit(Contact* pc);

3.3Contact.c文件

#include"Contact.h"void InitContact(Contact* pc)
{// 此时通讯录是空的,应先为通讯录分配空间pc->data = (PeoInfo*)malloc(sizeof(PeoInfo) * 4);// 如果分配成功,将通讯录的size设为0,capacity设为初识大小pc->size = 0;pc->capacity = 4;//将文档的信息传递到动态内存里,函数实现在下方LoadContact(pc);
}
void LoadContact(Contact* pc)
{// 以读的形式打开文件FILE* pf = fopen("contact.txt", "rb");if (pf == NULL){perror("fopen");return;}// 将文件中的内容加载到通讯录中// 这里用fread函数,当fread函数读取的联系人信息数为0时,说明读取结束PeoInfo tmp = { 0 }; // 定义一个联系人信息的结构体,便于读取int i = 0;while (fread(&tmp, sizeof(PeoInfo), 1, pf)){CheckCapacity(pc); // 在这个函数中查看数组是否需要扩容,若需要,则扩容pc->data[i] = tmp;pc->size++;i++;}// 关闭文件fclose(pf);pf = NULL;return;
}
void CheckCapacity(Contact* pc)
{// 判断通讯录是否已满,若满,进行扩容if (pc->size == pc->capacity){PeoInfo* tmp = (PeoInfo*)realloc(pc, sizeof(PeoInfo) * 4);if (tmp == NULL){printf("realloc fail\n");return;}pc->data = tmp;// 若扩容成功,增大capacitypc->capacity *= 2;}}
void AddContact(Contact* pc)
{int num = 0;printf("添加人数:");scanf("%d", &num);// 输入要添加的联系人的信息// 这里pc->data为结构体数组,pc->data[pc->size]为其中的元素,也就是某一个联系人的信息for (int i = 0; i < num; i++){//判断通讯录是否满人CheckCapacity(pc);printf("请输入名字\n");scanf("%s", pc->data[pc->size].name);printf("请输入性别\n");scanf("%s", pc->data[pc->size].sex);printf("请输入年龄\n");scanf("%d", &pc->data[pc->size].age);printf("请输入电话\n");scanf("%s", pc->data[pc->size].phone);pc->size++; // 将存入的联系人的数量加1}
}
void DeleteContact(Contact* pc)
{int ret = 0;//记录寻找的下标值printf("请输入要删除的联系人的名字\n");char name[20];scanf("%s", name);// 定义一个新函数find,用来查找是否有这个联系人// 如果有,返回联系人的下标,如果没有,返回-1for (int i = 0; i < pc->size; i++){if (strcmp(pc->data[i].name, name) == 0){ret = i; break;}}if (ret){printf("不存在");}else {for (int i = ret; i < pc->size - 1; i++){pc->data[i] = pc->data[i + 1];}pc->size--;}}
void SearchContact(Contact* pc)
{int ret = 0;printf("请输入要查找的联系人的名字\n");char name[20];scanf("%s", name);// 利用已经定义的find函数进行查找for (int i = 0; i < pc->size; i++){if (strcmp(pc->data[i].name, name) == 0){ret = i; break;}}if (ret){printf("没有找到该联系人\n");}else{// 如果找到,打印该联系人的信息,首先打印五个标题printf("%-10s\t%-10s\t%-5s\t%-15s\n", "姓名", "性别", "年龄", "电话");printf("%-10s\t%-10s\t%-5d\t%-15s%\n",pc->data[ret].name,pc->data[ret].sex,pc->data[ret].age,pc->data[ret].phone);}}
void ModifyContact(Contact* pc)
{int ret = 0;printf("请输入要查找的联系人的名字\n");char name[20];scanf("%s", name);// 利用已经定义的find函数进行查找for (int i = 0; i < pc->size; i++){if (strcmp(pc->data[i].name, name) == 0){ret = i; break;}}if (ret){printf("没有找到该联系人\n");}else{printf("请输入名字\n");scanf("%s", pc->data[ret].name);printf("请输入性别\n");scanf("%s", pc->data[ret].sex);printf("请输入年龄\n");scanf("%d", &pc->data[ret].age);printf("请输入电话\n");scanf("%s", pc->data[ret].phone);}}
// 在这个函数内打印所有联系人的信息
void PrintContact(Contact* pc)
{// 首先打印五个标题printf("%-10s\t%-10s\t%-5s\t%-15s\n", "姓名", "性别", "年龄", "电话");// 然后用for循环打印所有联系人的信息for (int i = 0; i < pc->size; i++){printf("%-10s\t%-10s\t%-5d\t%-15s\n",pc->data[i].name,pc->data[i].sex,pc->data[i].age,pc->data[i].phone	);}
}
void SaveContact(Contact* pc)
{FILE* p = fopen("contact.txt", "wb");if (p == NULL){perror("SaveContact");}else {int i = 0;for (i; i < pc->size; i++){fwrite(pc->data + i, sizeof(PeoInfo), 1, p);}fclose(p);p = NULL;printf("保存成功");}}
void Exit(Contact* pc)
{//销毁空间free(pc->data);pc->data = NULL;pc->size = 0;pc->capacity = 0;
}

总结

         在写动态存储文件版的通讯录,我们得学会动态存储和文件操作。

         只有不断的掌握知识,我们才能敲代码得心应手,在不断的学习里,逐渐进步。

                                                                                                      -------------小菜TQ02

相关文章:

C语言之通讯录(动态 存储文件版)

目录 前言 一.基本思路 二.代码的实现 2.1通讯录菜单 2.2通讯录的定义及功能 2.3函数实现 2.3.1初始化通讯录 2.3.2文件信息传递到通讯录里 2.3.3扩容通讯录 2.3.4增加联系人 2.3.5删除联系人 2.3.6查询联系人 2.3.7修改联系人 2.3.8打印通讯录 2.3.9信息保留在文…...

Linux 工具

文章目录一、软件包管理&#xff1a;yum1. 软件的生态环境2. yum 的使用3. yum 源及分类4. 在 centos 7.6 下更新 yum 源到国内镜像5. yum 命令二、编辑器&#xff1a;vim1. 命令模式2. 底行模式3. 插入模式4. 替换模式和视图模式5. vim 配置三、编译器&#xff1a;gcc/g1. C语…...

Java知识复习(七)常见的设计模式(装饰、代理、观察、策略、建造)

前言 参考书籍&#xff1a;《秒懂设计模式》 1、装饰器模式&#xff08;Decorator&#xff09; 1、装饰器模式&#xff1a;对原始对象动态地进行“包装”&#xff0c;是对类实例“装饰”的结果&#xff1b;类似于继承的效果&#xff0c;但这个过程是动态的&#xff0c;是可设…...

Linux系统看门狗应用编程

目录看门狗应用编程介绍打开设备获取设备支持哪些功能&#xff1a;WDIOC_GETSUPPORT获取/设置超时时间&#xff1a;WDIOC_GETTIMEOUT、WDIOC_SETTIMEOUT开启/关闭看门狗&#xff1a;WDIOC_SETOPTIONS喂狗&#xff1a;WDIOC_KEEPALIVE看门狗应用编程实战在产品化的嵌入式系统中&…...

Spring MVC 源码- LocaleResolver 组件

LocaleResolver 组件LocaleResolver 组件&#xff0c;本地化&#xff08;国际化&#xff09;解析器&#xff0c;提供国际化支持回顾先来回顾一下在 DispatcherServlet 中处理请求的过程中哪里使用到 LocaleResolver 组件&#xff0c;可以回到《一个请求的旅行过程》中的 Dispat…...

Servlet

Servlet1 简介2 快速入门3 执行流程4 生命周期5 方法介绍6 体系结构7 urlPattern配置8 XML配置1 简介 Servlet是JavaWeb最为核心的内容&#xff0c;它是Java提供的一门动态web资源开发技术。 使用Servlet就可以实现&#xff0c;根据不同的登录用户在页面上动态显示不同内容。 …...

简单的周总结

做一个简单的周总结。 校 OJ 上打了近 7 场比赛&#xff0c;ZR 及其他平台各一两场左右。 头几场打的中规中矩&#xff0c;分数大致在 100-200 左右&#xff0c;与同学分数差别不太大&#xff0c;但也没有很突出。 后面几场比较爆炸&#xff0c;分数一直在 100 以下&#xff0…...

Elasticsearch7.8.0版本进阶——IK中文分词器

目录一、ES 的默认分词器测试示例二、IK 中文分词器2.1、IK 中文分词器下载地址2.2、ES 引入IK 中文分词器2.3、IK 中文分词器测试示例三、ES 扩展词汇测试示例一、ES 的默认分词器测试示例 通过 Postman 发送 GET 请求查询分词效果&#xff0c;在消息体里&#xff0c;指定要分…...

一个阿里P6的说不会接口自动化测试,他不会是自己评的吧...

序 近期和一个阿里的测试工程师交流了一波&#xff0c;他竟然说我不会接口自动化测试&#xff0c;我当场就不服了我说你P6自己评级的吧&#xff0c;今天就带大家好好盘一盘接口自动化&#xff0c;本着以和大家交流如何实现高效的接口测试为出发点&#xff0c;本文包含了我在接…...

规则引擎与风控系统04:风控系统实例(下)

上一节把风控实例的基础代码都撸了出来。接下来再来把核心服务代码和规则文件写出来。 因为有了实体类、Dao,所以接来下就可以写服务类了。之前说过这个实例就是要实现两个目的: 1、一分钟内连续访问三次以上,就会被直接封杀; 2、黑名单用户登录会记录可疑事件。 所以服务类…...

我为什么选择Linux mint 21.1 “Vera“ ? Mint安装优化调教指南(分辨率DPI)

前言&#xff1a;为什么是Mint 笔者算是Linux老用户了&#xff0c;作为一个后端开发&#xff0c;尝试了多种不同发行版。 一开始是Manjaro这种Arch系&#xff0c;但是其对于开发而言实在是太过不稳定&#xff1b;每次滚动更新都要解决很多冲突。不适合当生产力&#xff08;本…...

雅思经验(十四)

剑10 test3 阅读p3这篇阅读比较难做下来&#xff0c;主要是这个题材我们不太熟悉&#xff0c;介绍了一种成为拉皮塔人&#xff0c;他们在太平洋上航行&#xff0c;很多岛屿上都有他们足迹&#xff0c;后来人们发掘、探索他们的历史的故事。1.derelict 与 abandoned 主要是前面的…...

刚来的薪资20k,是我的2倍,我是真的卷不过,真的太变态了

在这个行业爬摸滚打5年了&#xff0c;从最开始点点点的功能测试到现在到现在成为高级测试&#xff0c;工资也翻了几倍&#xff0c;简单的说几句吧 改变的开始 之所以改变的原因很简单&#xff0c;我快被新来的卷死了&#xff0c;新来的本科是某211的&#xff0c;干劲十足&…...

五、DeepWalk、Node2Vec论文精读与代码实战【CS224W】(Datawhale组队学习)

开源内容&#xff1a;https://github.com/TommyZihao/zihao_course/tree/main/CS224W 子豪兄B 站视频&#xff1a;https://space.bilibili.com/1900783/channel/collectiondetail?sid915098 斯坦福官方课程主页&#xff1a;https://web.stanford.edu/class/cs224w 文章目录D…...

学习 Python 之 Pygame 开发魂斗罗(四)

学习 Python 之 Pygame 开发魂斗罗&#xff08;四&#xff09;继续编写魂斗罗1. 创建子弹类2. 根据玩家方向和状态设置子弹发射的位置(1). 站立向右发射子弹(2). 站立向左发射子弹(3). 站立朝上发射子弹(4). 蹲下发射子弹(5). 向斜方发射子弹(6). 奔跑时发射子弹(7). 跳跃时发射…...

Linux 基础知识:指令与shell

目录一、操作系统二、指令三、shell一、操作系统 什么是操作系统&#xff1f; 单纯的操作系统应该是指操作系统内核。内核的作用就是管理计算机的软硬件资源&#xff0c;让计算机在合适的时候干合适的事情。 但是有一个问题&#xff0c;并不是人人都会直接通过内核来操作计算机…...

【数通网络交换基础梳理1】二层交换机、以太网帧、MAC地址数据帧转发原理详解

一、网络模型 万年不变&#xff0c;先从模型结构分析&#xff0c;现在大家熟知的网络模型有两种。第一种是&#xff0c;OSI七层模型&#xff0c;第二种是TCP/IP模型。在实际运用中&#xff0c;参考更多的是TCP/IP模型。 OSI七层模型 TCP/IP模型 不需要全部理解&#xff0c;…...

《分布式技术原理与算法解析》学习笔记Day22

哈希与一致性哈希 在分布式系统中&#xff0c;哈希和一致性哈希是数据索引或者数据分布的常见实现方式。 数据分布设计原则 在分布式数据存储系统中&#xff0c;做存储方案选型时&#xff0c;一般会考虑以下因素&#xff1a; 数据均匀数据稳定节点异构性隔离故障域性能稳定…...

[MySQL]MySQL数据类型

文章目录数据类型分类数值类型tinyint类型bit类型float类型decimal类型字符串类型char类型varchar类型char和varchar对比日期和时间类型enum和set类型数据类型分类 MySQL中&#xff0c;支持各种各样的类型&#xff0c;比如表示数值的整型浮点型&#xff0c;文本、二进制类型、…...

利用steam搬砖信息差赚钱,单账号200+,小白也能轻松上手!

现在很多人在做互联网而且也赚到钱了&#xff0c;但还是有很多人赚不到钱&#xff0c;这是为什么&#xff1f; 这里我不得不说一个词叫做赛道&#xff0c;也就是选择&#xff0c;选择大于努力&#xff0c;项目本身大于一切&#xff0c;90%的人都觉得直播带货赚钱&#xff0c;但…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

【git】把本地更改提交远程新分支feature_g

创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台

🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...

C++:多态机制详解

目录 一. 多态的概念 1.静态多态&#xff08;编译时多态&#xff09; 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1&#xff09;.协变 2&#xff09;.析构函数的重写 5.override 和 final关键字 1&#…...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机&#xff08;无人驾驶飞行器&#xff0c;UAV&#xff09;技术的快速发展&#xff0c;其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统&#xff0c;无人机的“黑飞”&…...

android13 app的触摸问题定位分析流程

一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...

基于Java+VUE+MariaDB实现(Web)仿小米商城

仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意&#xff1a;运行前…...

【UE5 C++】通过文件对话框获取选择文件的路径

目录 效果 步骤 源码 效果 步骤 1. 在“xxx.Build.cs”中添加需要使用的模块 &#xff0c;这里主要使用“DesktopPlatform”模块 2. 添加后闭UE编辑器&#xff0c;右键点击 .uproject 文件&#xff0c;选择 "Generate Visual Studio project files"&#xff0c;重…...