数据结构小项目----通讯录的实现(这里用链表实现) 超详细~~~~૮(˶ᵔ ᵕ ᵔ˶)ა
目录
Contact.h说明:
结构体与头文件的包含: 编辑
函数在头文件的声明与定义:
Contact.c中各个函数的实现:
1.检查链表中的数据是否满了,满了就扩容
2.链表的尾插
3.链表的删除
4.查找名字是否匹配
5.初始化通讯录
6. 通讯录的摧毁
7.添加联系人的信息
8.删除联系人的信息
9.修改联系人信息
10.查找联系人
11.通讯录当前的联系人展示
ConTest.c源文件:
测试数据:
最后完整代码展示:
Contact.h:
Contact.c:
ConTest.c:
Contact.h说明:
概述:为了实现这个小项目,我开创了一个头文件:Contact.h .和两个源文件:Contact.c,ConTest.c,在Contact.h中进行结构体的声明,函数的声明和头文件的包含。Contact.c文件主要用于各个函数的实现,而ConTest则用于测试函数。
结构体与头文件的包含: 
这里通过结构体数组来进行数据的插入与删除操作,为了后续的书写方便,将各个结构体变量的名字重新定义为其缩写形式(底层原理是顺序表)
函数在头文件的声明与定义:
void SLCheckCapacity(Contact* pocn);//用于顺序表的扩容
void SLPushBack(Contact* ps, ConDataType x);//顺序表的尾插
void SLErase(Contact* ps, int pos);//顺序表的删除
int FindByName(Contact* pocn, char name[]);//查找名字是否匹配void ContactInit(Contact* pocn);//通讯录的初始化
void ContactDestory(Contact* pocn);//通讯录的摧毁void ContactAdd(Contact* pocn);//通讯录的增加联系人
void ContactDel(Contact* pocn);//通讯录的删除联系人
void ContactModify(Contact* pocn);//通讯录的修改联系人信息
void ContactFind(Contact* pocn);//通讯录的查找
void ContactShow(Contact* pocn);//当前通讯录的信息的展示
Contact.c中各个函数的实现:
1.检查链表中的数据是否满了,满了就扩容
代码详解:
//检查链表中的数据是否满了,满了就扩容
void SLCheckCapacity(Contact* pocn) {if (pocn->size == pocn->capacity) {int newCapacity = pocn->capacity == 0 ? 4 : 2 * pocn->capacity;//这里通过realloc来申请空间ConDataType* tmp = (ConDataType*)realloc(pocn->arr, newCapacity * sizeof(ConDataType));if (tmp == NULL) {perror("realloc fail!");exit(1);}//扩容成功pocn->arr = tmp;//注意要将当前的指针指向开创好的空间pocn->capacity = newCapacity;//容量也不要遗漏}
}
由于顺序表是由数组实现的,如果定义一个静态数组,很不利于数据的存储。定义得太大浪费空间,定义得太小空间不够,这里我选择使用动态链表的形式实现这个问题,所以这里定义了一个函数SLCheckCapacity来检查链表的大小(size)是否超过其最大容量(capacity)。如果超过了,就需要进行扩容操作。没有就不需要进行任何操作。同时,为了和里这里扩容两倍。
2.链表的尾插
代码详解:
//链表的尾插
void SLPushBack(Contact* ps, ConDataType x) {assert(ps);SLCheckCapacity(ps);ps->arr[ps->size++] = x;
}
首先判断这里的结构体指针是否为空,简单粗暴的方法:断言(assert),注意要引用头文件#include<assert.h>。接着要检查顺序表的容量是否满了,如果满了就扩容。 接着将数据插入尾部。
3.链表的删除
代码解释:
//链表的删除
void SLErase(Contact* ps, int pos) {assert(ps);assert(pos >= 0 && pos < ps->size);//pos以后的数据往前挪动一位for (int i = pos; i < ps->size - 1; i++){ps->arr[i] = ps->arr[i + 1];//ps->arr[i-2] = ps->arr[i-1];}ps->size--;
}
4.查找名字是否匹配
代码解释:
//查找名字是否匹配
int FindByName(Contact* pocn, char name[]) {for (int i = 0; i < pocn->size; i++) {if (strcmp(pocn->arr[i].name, name) == 0) {return i;}}return -1;
}
如果有遗忘strcmp的小伙伴记得查收~
strcmp比较两个字符串的大小,一个字符一个字符比较,按ASCLL码比较
标准规定:
第一个字符串大于第二个字符串,则返回大于0的数字
第一个字符串等于第二个字符串,则返回0
第一个字符串小于第二个字符串,则返回小于0的数字
5.初始化通讯录
代码解释:
//初始化通讯录
void ContactInit(Contact* pocn) {pocn->arr = NULL;pocn->capacity = pocn->size = 0;
}
6. 通讯录的摧毁
代码解释:
//通讯录的摧毁
void ContactDestory(Contact* pocn) {assert(pocn);if (pocn->arr) {free(pocn->arr);}pocn->arr = NULL;pocn->capacity = pocn->size = 0;
}
7.添加联系人的信息
代码解释:
//添加联系人的信息
void ContactAdd(Contact* pocn) {Info info;//输入各个联系人的信息printf("请输入联系人姓名:\n");scanf("%s", info.name);printf("请输入联系人年龄:\n");scanf("%d", &info.age);printf("请输入联系人性别:\n");scanf("%s", info.gender);printf("请输入联系人电话:\n");scanf("%s", info.tel);printf("请输入联系人地址:\n");scanf("%s", info.addr);//用尾插法进行数据的增添SLPushBack(pocn, info);
}
输入联系人的各个信息后将其尾插到链表后
8.删除联系人的信息
代码解释:
//删除联系人的信息
void ContactDel(Contact* pocn) {//删除之前要先查找//找到之后可以删除找不到,就不能进行删除操作printf("请输入要删除的联系人名字:\n");char name[NAME_MAX];scanf("%s", name);//定义findIndex来判断是否存在联系人信息int findIndex = FindByName(pocn, name);if (findIndex < 0) {printf("要删除的信息不存在!\n");return;}//存在就删除SLErase(pocn, findIndex);printf("联系人删除成功!\n");
}
9.修改联系人信息
代码解释:
//修改联系人信息
void ContactModify(Contact* pocn) {//修改之前先查找//如果没有找到,就无法进行修改操作char name[NAME_MAX];printf("请输入要修改的联系人姓名:\n");scanf("%s", name);int findIndex = FindByName(pocn, name);if (findIndex < 0) {printf("要修改的联系人找不到!\n");return;}//修改后输入新的联系人的信息printf("请输入姓名:\n");scanf("%s", pocn->arr[findIndex].name);printf("请输入年龄:\n");scanf("%d", &pocn->arr[findIndex].age);printf("请输入性别:\n");scanf("%s", pocn->arr[findIndex].gender);printf("请输入电话:\n");scanf("%s", pocn->arr[findIndex].tel);printf("请输入地址:\n");scanf("%s", pocn->arr[findIndex].addr);printf("联系人修改成功!\n");
}
10.查找联系人
代码解释:
//查找联系人
void ContactFind(Contact* pocn) {printf("请输入要查找的联系人姓名:\n");char name[NAME_MAX];scanf("%s", name);int findIndex = FindByName(pocn, name);if (findIndex < 0) {printf("找不到该联系人,联系人不存在!\n");return;}else printf("找到了,输出对应信息:\n");printf("%s %s %s %s %s\n", "姓名", "年龄", "性别", "电话", "地址");printf("%s %d %s %s %s\n",pocn->arr[findIndex].name,pocn->arr[findIndex].age,pocn->arr[findIndex].gender,pocn->arr[findIndex].tel,pocn->arr[findIndex].addr);
}
11.通讯录当前的联系人展示
代码解释:
//通讯录当前的联系人展示
void ContactShow(Contact* pocn) {printf("%s %s %s %s %s\n", "姓名", "年龄", "性别", "电话", "地址");for (int i = 0; i < pocn->size; i++) {printf("%s %d %s %s %s\n",pocn->arr[i].name,pocn->arr[i].age,pocn->arr[i].gender,pocn->arr[i].tel,pocn->arr[i].addr);}
}
ConTest.c源文件:
代码详解:
//引入头文件
#include"Contact.h"void menu()//菜单的打印
{printf("-------------------------请输入--------------------------------\n");printf("----------------1.增加联系人 2.删除联系人---------------------\n");printf("---------------3.修改联系人 4.查找联系人---------------------\n");printf("---------------5.查看通讯录 0.退出通讯录---------------------\n");printf("---------------------------------------------------------------\n");
}int main()
{int op = -1;Contact con;ContactInit(&con);do {menu();printf("请选择操作:");scanf("%d", &op);//这里按照菜单的指示来选择操作switch (op) {//各个数字对应各个的操作case 1:ContactAdd(&con);break;case 2:ContactDel(&con);break;case 3:ContactModify(&con);break;case 4:ContactFind(&con);break;case 5:ContactShow(&con);break;case 0:printf("通讯录退出中……\n");break;default :break;}} while (op != 0);ContactDestory(&con);//注意结束时要摧毁通讯录,防止内存泄漏return 0;
}
在ConTest文件中,主要是实现菜单的打印与各个函数操作的选择
测试数据:

最后完整代码展示:
Contact.h:
#include<assert.h>
#include<stdlib.h>//为了后续方便,这里将所要用到的数组的数据都重新定义
#define NAME_MAX 100
#define GENDER_MAX 10
#define TEL_MAX 12
#define ADDR_MAX 100
//联系人信息的存储(用结构体实现)
typedef struct PresonInformation
{char name[NAME_MAX];int age;char gender[GENDER_MAX];char tel[TEL_MAX];char addr[ADDR_MAX];
}Info;typedef Info ConDataType;
//对链表的声明与定义(结构体数组),用于对上述结构体信息存储
typedef struct SeqList
{ConDataType* arr;int capacity;int size;
}Contact;void SLCheckCapacity(Contact* pocn);//用于顺序表的扩容
void SLPushBack(Contact* ps, ConDataType x);//顺序表的尾插
void SLErase(Contact* ps, int pos);//顺序表的删除
int FindByName(Contact* pocn, char name[]);//查找名字是否匹配void ContactInit(Contact* pocn);//通讯录的初始化
void ContactDestory(Contact* pocn);//通讯录的摧毁void ContactAdd(Contact* pocn);//通讯录的增加联系人
void ContactDel(Contact* pocn);//通讯录的删除联系人
void ContactModify(Contact* pocn);//通讯录的修改联系人信息
void ContactFind(Contact* pocn);//通讯录的查找
void ContactShow(Contact* pocn);//当前通讯录的信息的展示
Contact.c:
#include"Contact.h"
//检查链表中的数据是否满了,满了就扩容
void SLCheckCapacity(Contact* pocn) {if (pocn->size == pocn->capacity) {int newCapacity = pocn->capacity == 0 ? 4 : 2 * pocn->capacity;//这里通过realloc来申请空间ConDataType* tmp = (ConDataType*)realloc(pocn->arr, newCapacity * sizeof(ConDataType));if (tmp == NULL) {perror("realloc fail!");exit(1);}//扩容成功pocn->arr = tmp;//注意要将当前的指针指向开创好的空间pocn->capacity = newCapacity;//容量也不要遗漏}
}
//链表的尾插
void SLPushBack(Contact* ps, ConDataType x) {assert(ps);SLCheckCapacity(ps);ps->arr[ps->size++] = x;
}
//链表的删除
void SLErase(Contact* ps, int pos) {assert(ps);assert(pos >= 0 && pos < ps->size);//pos以后的数据往前挪动一位for (int i = pos; i < ps->size - 1; i++){ps->arr[i] = ps->arr[i + 1];//ps->arr[i-2] = ps->arr[i-1];}ps->size--;
}
//查找名字是否匹配
int FindByName(Contact* pocn, char name[]) {for (int i = 0; i < pocn->size; i++) {if (strcmp(pocn->arr[i].name, name) == 0) {return i;}}return -1;
}//初始化通讯录
void ContactInit(Contact* pocn) {pocn->arr = NULL;pocn->capacity = pocn->size = 0;
}
//通讯录的摧毁
void ContactDestory(Contact* pocn) {assert(pocn);if (pocn->arr) {free(pocn->arr);}pocn->arr = NULL;pocn->capacity = pocn->size = 0;
}
//添加联系人的信息
void ContactAdd(Contact* pocn) {Info info;//输入各个联系人的信息printf("请输入联系人姓名:\n");scanf("%s", info.name);printf("请输入联系人年龄:\n");scanf("%d", &info.age);printf("请输入联系人性别:\n");scanf("%s", info.gender);printf("请输入联系人电话:\n");scanf("%s", info.tel);printf("请输入联系人地址:\n");scanf("%s", info.addr);//用尾插法进行数据的增添SLPushBack(pocn, info);
}//删除联系人的信息
void ContactDel(Contact* pocn) {//删除之前要先查找//找到之后可以删除找不到,就不能进行删除操作printf("请输入要删除的联系人名字:\n");char name[NAME_MAX];scanf("%s", name);//定义findIndex来判断是否存在联系人信息int findIndex = FindByName(pocn, name);if (findIndex < 0) {printf("要删除的信息不存在!\n");return;}//存在就删除SLErase(pocn, findIndex);printf("联系人删除成功!\n");
}
//修改联系人信息
void ContactModify(Contact* pocn) {//修改之前先查找//如果没有找到,就无法进行修改操作char name[NAME_MAX];printf("请输入要修改的联系人姓名:\n");scanf("%s", name);int findIndex = FindByName(pocn, name);if (findIndex < 0) {printf("要修改的联系人找不到!\n");return;}//修改后输入新的联系人的信息printf("请输入姓名:\n");scanf("%s", pocn->arr[findIndex].name);printf("请输入年龄:\n");scanf("%d", &pocn->arr[findIndex].age);printf("请输入性别:\n");scanf("%s", pocn->arr[findIndex].gender);printf("请输入电话:\n");scanf("%s", pocn->arr[findIndex].tel);printf("请输入地址:\n");scanf("%s", pocn->arr[findIndex].addr);printf("联系人修改成功!\n");
}
//查找联系人
void ContactFind(Contact* pocn) {printf("请输入要查找的联系人姓名:\n");char name[NAME_MAX];scanf("%s", name);int findIndex = FindByName(pocn, name);if (findIndex < 0) {printf("找不到该联系人,联系人不存在!\n");return;}else printf("找到了,输出对应信息:\n");printf("%s %s %s %s %s\n", "姓名", "年龄", "性别", "电话", "地址");printf("%s %d %s %s %s\n",pocn->arr[findIndex].name,pocn->arr[findIndex].age,pocn->arr[findIndex].gender,pocn->arr[findIndex].tel,pocn->arr[findIndex].addr);
}
//通讯录当前的联系人展示
void ContactShow(Contact* pocn) {printf("%s %s %s %s %s\n", "姓名", "年龄", "性别", "电话", "地址");for (int i = 0; i < pocn->size; i++) {printf("%s %d %s %s %s\n",pocn->arr[i].name,pocn->arr[i].age,pocn->arr[i].gender,pocn->arr[i].tel,pocn->arr[i].addr);}
}
ConTest.c:
//引入头文件
#include"Contact.h"void menu()//菜单的打印
{printf("-------------------------请输入--------------------------------\n");printf("----------------1.增加联系人 2.删除联系人---------------------\n");printf("---------------3.修改联系人 4.查找联系人---------------------\n");printf("---------------5.查看通讯录 0.退出通讯录---------------------\n");printf("---------------------------------------------------------------\n");
}int main()
{int op = -1;Contact con;ContactInit(&con);do {menu();printf("请选择操作:");scanf("%d", &op);//这里按照菜单的指示来选择操作switch (op) {//各个数字对应各个的操作case 1:ContactAdd(&con);break;case 2:ContactDel(&con);break;case 3:ContactModify(&con);break;case 4:ContactFind(&con);break;case 5:ContactShow(&con);break;case 0:printf("通讯录退出中……\n");break;default :break;}} while (op != 0);ContactDestory(&con);//注意结束时要摧毁通讯录,防止内存泄漏return 0;
}
博客到这里也是结束了,制作不易,喜欢的小伙伴可以点赞加关注支持下博主,这对我真的很重要~~
相关文章:
数据结构小项目----通讯录的实现(这里用链表实现) 超详细~~~~૮(˶ᵔ ᵕ ᵔ˶)ა
目录 Contact.h说明: 结构体与头文件的包含: 编辑 函数在头文件的声明与定义: Contact.c中各个函数的实现: 1.检查链表中的数据是否满了,满了就扩容 2.链表的尾插 3.链表的删除 4.查找名字是否匹配 5.初始化通讯…...
Electron Apple SignIn 登录
本人写博客,向来主张:代码要完整,代码可运行,文中不留下任何疑惑。 最讨厌写博客,代码只留下片段,文中关键的东西没写清楚。之前看了那么多文章,就是不告诉我clientId从哪来的。 官方资料地址&…...
常用中间件漏洞
IIS6 IIS7 安装 控制面板-----打开关闭windows功能 添加角色-----添加IIS 启动之后访问localhost 复现 服务器换成IIS7 访问报错 大概就是缺少CGI模块 问题解决 添加php-cgi的路径 添加脚本映射 修改php.ini文件 将 cgi.fix_pathinfo1 然后设置一个图片 访问 在后缀加上/.…...
Windows系统使用手册
点击前往查看🔗我的博客文章目录 Windows系统使用手册 文章目录 Windows系统使用手册Windows10解决大小核调度问题Windows系统安装软件Windows系统Typora快捷键Windows系统压缩包方式安装redisWindows安装dockerWindows系统的docker设置阿里源Windows系统下使用doc…...
mp4文件可以转成mp3音频吗
现在是个非常流行刷短视频一个年代,刷短视似乎成了人们休闲娱乐的一种方式,在日常刷短视频过程中,肯定会有很多同学被短视频 bgm 神曲洗脑,比如很多被网红翻唱带火的歌曲,例如其中"不负人间”,就是其中…...
Java-IO流【登录注册小项目】
♥️作者:白日参商 🤵♂️个人主页:白日参商主页 ♥️坚持分析平时学习到的项目以及学习到的软件开发知识,和大家一起努力呀!!! 🎈🎈加油! 加油!…...
数字化金融时代:探讨全球金融科技创新的最新动态
在当今数字化金融时代,金融科技创新如影随形,迅猛发展。本文将深入探讨全球范围内金融科技的最新动态,剖析各地新兴趋势与突破。从区块链技术的应用到人工智能在金融领域的崭露头角,我们将一一解读这个正在不断演变的金融科技画卷…...
LeetCode:206. 反转链表
力扣链接 算法思想:由于单链表是单向的,想要对当前元素进行操作,需找到前一个元素。本题利用双指针,初始pre指针指向NULL,cur指针指向head.再对局部翻转之前,先把下一个结点存到temp指针中。当进行完如下代…...
linux 安装nginx
介绍 官网 https://nginx.org/en/download.html 在安装nginx前首先要确认系统中安装了gcc、pcre-devel、zlib-devel、openssl-devel linux 检查是否安装过某软件包 yum -y install gcc pcre-devel zlib-devel openssl openssl-devel #下载 wget https://nginx.org/downloa…...
1.C语言——基础知识
C语言基础知识 1.第一个C语言程序2.注释3.标识符4.关键字5.数据类型6.变量7.常量8.运算符9.输入输出输入输出 1.第一个C语言程序 C语言的编程框架 #include <stdio.h> int main() {/* 我的第一个 C 程序 */printf("Hello, World! \n");return 0; }2.注释 单行…...
Redis 存在线程安全问题吗?为什么?
一个工作了 5 年的粉丝私信我。 他说自己准备了半年时间,想如蚂蚁金服,结果第一面就挂了,非常难过。 问题是: “Redis 存在线程安全问题吗?” 一、问题解析 关于这个问题,我从两个方面来回答。 第一个&a…...
无人机测绘助力实现高效、安全的城市规划
随着城市化进程的不断加快,城市规划显得尤为重要。而无人机测绘技术作为一种创新的工具,为城市规划提供了更加高效、安全的解决方案。它通过快速、精确的数据采集和分析,为行业提供有力的决策支持,助力城市规划的现代化和可持续发…...
实验七 RMAN恢复管理器
🕺作者: 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux 😘欢迎关注:👍点赞🙌收藏✍️留言 🏇码字不易,你的👍点赞🙌收藏❤️关注对我真的很重要&…...
未来 AI 可能给哪些产业带来哪些进步与帮助?
AI时代如何要让公司在创新领域领先吗?拥抱这5种创新技能,可以帮助你的公司应对不断变化。包括人工智能、云平台应用、数据分析、 网络安全和体验设计。这些技能可以帮助你提高业务效率、保护公司知识资产、明智决策、满足客户需求并提高销售额。 现在就加…...
Java医院信息管理系统
技术框架: springboot shiro layui jquery thymeleaf nginx 有需要的可以联系我。 运行环境: jdk8 mysql IntelliJ IDEA maven项目功能: 本项目是用springbootlayuishiro写的医院管理系统,系统的业务比较复杂&#x…...
QT+OSG/osgEarth编译之八十:ive+Qt编译(一套代码、一套框架,跨平台编译,版本:OSG-3.6.5插件库osgdb_ive)
文章目录 1、osgdb_ive介绍2、文件分析3、pro文件4、编译实践1、osgdb_ive介绍 通过osgdb_ive,OpenSceneGraph开源库能方便地读取ive格式的三维文件。 ive(Interchangeable Virtual Environment)是一种三维图形数据交换格式,主要用于虚拟现实和增强现实领域的场景数据交…...
Webpack5入门到原理3:基本配置
在开始使用 Webpack 之前,我们需要对 Webpack 的配置有一定的认识。 5 大核心概念 entry(入口) 指示 Webpack 从哪个文件开始打包 output(输出) 指示 Webpack 打包完的文件输出到哪里去,如何命名等 l…...
全开源多城市同城信息小程序源码(Laravel 框架),同城分类信息发布便民小程序系统【非DZ】
同城生活分类信息小程序,人才招聘、房产二手 多城市地区同城分类信息发布,商家入驻等功能 小程序前后端代码开源无加密,可进行二次开发 【源码运行要求】 1、需要已认证的微信小程序 2、已备案的域名及服务器空间 推荐使用宝塔面板LinuxPHP…...
PHP学习笔记1
//语法错误(syntax error)在语法分析阶段,源代码并未被执行,故不会有任何输出。 /* 【命名规则】 */ 常量名 类常量建议全大写,单词间用下划线分隔 // MIN_WIDTH 变量名建议用下划线方式分隔 // $var_na…...
C语言从入门到实战——文件操作
文件操作 前言一、 为什么使用文件二、 什么是文件2.1 程序文件2.2 数据文件2.3 文件名 三、 二进制文件和文本文件四、 文件的打开和关闭4.1 流和标准流4.1.1 流4.1.2 标准流 4.2 文件指针4.3 文件的打开和关闭4.4 文件的路径 五、 文件的顺序读写5.1 顺序读写函数介绍fgetcfp…...
解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
04-初识css
一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...
【HTML-16】深入理解HTML中的块元素与行内元素
HTML元素根据其显示特性可以分为两大类:块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)
前言: 最近在做行为检测相关的模型,用的是时空图卷积网络(STGCN),但原有kinetic-400数据集数据质量较低,需要进行细粒度的标注,同时粗略搜了下已有开源工具基本都集中于图像分割这块,…...
LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...
GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...
NPOI操作EXCEL文件 ——CAD C# 二次开发
缺点:dll.版本容易加载错误。CAD加载插件时,没有加载所有类库。插件运行过程中用到某个类库,会从CAD的安装目录找,找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库,就用插件程序加载进…...
解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist
现象: android studio报错: [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决: 不要动CMakeLists.…...

