5.1 C/C++ 使用文件与指针

C/C++语言是一种通用的编程语言,具有高效、灵活和可移植等特点。C语言主要用于系统编程,如操作系统、编译器、数据库等;C语言是C语言的扩展,增加了面向对象编程的特性,适用于大型软件系统、图形用户界面、嵌入式系统等。C/C++语言具有很高的效率和控制能力,但也需要开发人员自行管理内存等底层资源,对于初学者来说可能会有一定的难度。

读文件并输出内容: 逐个字符读取文件中的数据,直到遇到EOF结束标志是停止输出.

#include <stdio.h>
#include <stdlib.h>int Read_File(FILE *fp)
{if (fp == NULL)return 0;char ch;// while ((ch = fgetc(fp)) != EOF)while (!feof(fp)){ch = fgetc(fp);if (feof(fp))break;printf("%c", ch);}
}int main(int argc, char* argv[])
{FILE *fp = fopen("c:/lyshark.log", "r");Read_File(fp);system("pause");return 0;
}

堆空间读取数据: 首先我们将数据读入到自己分配的堆空间中,然后直接输出堆空间中的字符串.

#include <stdio.h>
#include <stdlib.h>int main(int argc, char* argv[])
{FILE *fp = fopen("c:/lyshark.log", "r");char *buffer = malloc(sizeof(char)* 1024);while (feof(fp) == 0){memset(buffer, 0, 1024);fgets(buffer, 1024, fp);printf("%s", buffer);}system("pause");return 0;
}

一种特殊的文件操作: 这里我们举一个批量执行命令的案例,并通过格式化输出到缓冲区中.

#include <stdio.h>int main(int argc, char* argv[])
{char buffer[4096];FILE *fi = _popen("ipconfig", "r");while (fgets(buffer, 4096, fi) != NULL){fprintf(stdout, "%s", buffer);}system("pause");return 0;
}

写入字符串到文件: 将一个字符串写入到文件中,每次调用Write_File都可以写入一段字符串.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>int Write_File(char *path, char *msg)
{FILE *fp = fopen(path, "a+");if(fp== NULL) return -1;char ch, buffer[1024];int index = 0;while (msg[index] != '\0'){fputc(msg[index], fp);index++;}fclose(fp);return 1;
}int main(int argc, char* argv[])
{for (int x = 0; x < 10; x++)Write_File("c:/lyshark.log", "hello lyshark\n");system("pause");return 0;
}

实现动态数据存储(VIM): 通过循环实现动态接收用户输入数据,直到用户输入exit()命令后,才会停止程序运行.

#include <stdio.h>int main(int argc, char* argv[])
{FILE * fp = fopen("c:/lyshark.log", "w");if (fp == NULL)return -1;char buf[1024];while (1){memset(buf, 0, 1024);fgets(buf, 1024, stdin);if (strncmp("exit()", buf, 6) == 0)break;int index = 0;while (buf[index] != '\0')fputc(buf[index++], fp);}fclose(fp);system("pause");return 0;
}

创建临时文件: 通过调用tmpfile()命令就可以实现创建临时文件,该文件在程序结束后会自动释放.

#include <stdio.h>int main(int argc, char *argv[])
{FILE *temp;char c;if ((temp = tmpfile()) != NULL){fputs("hello lyshark\n", temp); // 向临时文件中写入要求内容}rewind(temp);                       // 文件指针返回文件首while ((c = fgetc(temp)) != EOF)    // 读取临时文件中内容printf("%c", c);fclose(temp);return 0;
}

重命名文件: 重命名文件则可以调用rename()这条命令,但需要提前打开文件后才能操作.

#include <stdio.h>int Rename_File(char *src_name, char *dst_name)
{FILE *fp = fopen(src_name, "r");if (fp != NULL){rename(src_name, dst_name);fclose(fp);}return 0;
}int main(int argc, char* argv[])
{Rename_File("c:/test.log", "c:/lyshark.log");system("pause");return 0;
}

删除特定文件: 时拿出文件则使用remove()函数即可,删除成功返回1,失败返回0.

#include <stdio.h>int Delete_File(char *file_name)
{FILE *fp;if ((fp = fopen(file_name, "r")) != NULL)fclose(fp);remove(file_name);if ((fp = fopen(file_name, "r")) == NULL)return 1;return 0;
}int main(int argc, char* argv[])
{Delete_File("c:/lyshark.log");system("pause");return 0;
}

实现小文件拷贝: 小文件的拷贝我们可以使用逐个字节的方式拷贝,这种方式拷贝较慢,且拷贝资源时大量占用栈空间.

#include <stdio.h>int Copy_File(const char *src,const char *dst)
{FILE *src_file = fopen(src, "rb");FILE *dst_file = fopen(dst, "wb");if (src_file == NULL || dst_file == NULL)return - 1;char buffer;while (fread(&buffer,sizeof(char),1,src_file) != 0){fwrite(&buffer, sizeof(char), 1, dst_file);}fcloseall();return 1;
}int main(int argc, char * argv[])
{Copy_File("c:/test.exe", "c:/lyshark.exe");system("pause");return 0;
}

实现大文件拷贝: 如果是大文件的拷贝,我们将不能使用栈来传递数据,我们需要开辟堆空间,来实现拷贝.

#include <stdio.h>
#include <stdlib.h>int Copy_File(const char *src, const char *dst)
{FILE *src_file = fopen(src, "rb");FILE *dst_file = fopen(dst, "wb");if (src_file == NULL || dst_file == NULL)return -1;char *buffer;buffer = (char *)malloc(sizeof(char)* 1024);   // 开辟一段堆空间memset(buffer, 0, 1024);                       // 对该空间进行初始化while (fread(buffer, sizeof(char), 1024, src_file) != 0){fwrite(buffer, sizeof(char), 1024, dst_file);memset(buffer, 0, 1024);}free(buffer);fcloseall();return 1;
}int main(int argc, char * argv[])
{Copy_File("c:/test.exe", "c:/lyshark.exe");system("pause");return 0;
}

实现两个文件的合并: 将两个文本文件中的内容aaa.log合并到bbb.log中.

#include <stdio.h>int Merge_File(const char *src, const char *dst)
{FILE *src_file = fopen(src, "r");FILE *dst_file = fopen(dst, "a+");if (src_file == NULL || dst_file == NULL)return -1;char buffer;fseek(dst_file, 0, SEEK_END);buffer = fgetc(src_file);while (!feof(src_file)){fputc(buffer, dst_file);buffer = fgetc(src_file);}fcloseall();return 1;
}int main(int argc, char * argv[])
{Merge_File("c:/aaa.log", "c:/bbb.log");system("pause");return 0;
}

读取文件总行数: 使用该方法可实现统计指定文件中文件的存在行数,该函数并未过滤特殊字符.

#include <stdio.h>
#include <stdlib.h>int Get_File_Line(FILE *fp)
{if (fp == NULL) return -1;char buffer[4096] = { 0 };int line = 0;while (fgets(buffer, 4096, fp) != NULL)++line;// 恢复指针起始位置fseek(fp, 0, SEEK_SET);return line + 1;
}int main(int argc, char* argv[])
{FILE *fp = fopen("c:/lyshark.log", "r");int line = Get_File_Line(fp);printf("文件总行数: %d \n", line);system("pause");return 0;
}

读取文件有效行数: 这个案例我们在上面的代码上稍加修改就能实现,我们主要筛选出符合规范的行.

#include <stdio.h>
#include <stdlib.h>// 该方法用于逐行验证是否符合规范
// 规范: 开头不能是#以及空白行,字符中必须存在:冒号.
int Verification(const char *buf)
{if (buf[0] == '#' || buf[0] == '\n' || strchr(buf, ':') == NULL)return 0;return 1;
}// 实现获取文件中符合要求的行数量
int Get_File_Line(FILE *fp)
{char buffer[1024] = { 0 };int index = 0;while (fgets(buffer, 1024, fp) != NULL){if (!Verification(buffer))    // 验证是否符合要求continue;                 // 不符合则跳过本次循环memset(buffer, 0, 1024);      // 符合则先来初始化内存index++;}fseek(fp, 0, SEEK_SET);return index;
}int main(int argc, char * argv[])
{FILE *fp = fopen("c:/conf.ini", "r");int line = Get_File_Line(fp);           // 获取文件有效行printf("有效行: %d \n", line);          // 输出符合要求的行数system("pause");return 0;
}

实现获取文件大小: 此处的文件大小指的是文件在磁盘中所占用的物理存储单位.

#include <stdio.h>int Get_File_Size(const char *file_name)
{FILE *fp;long file_size;if (fp = fopen(file_name, "r")){fseek(fp, 0, SEEK_END);file_size = ftell(fp);fcloseall();return file_size;}return 0;
}int main(int argc, char * argv[])
{long ret = Get_File_Size("c:/lyshark.exe");printf("文件大小是: %d 字节 \n", ret/1024);system("pause");return 0;
}

获取文本中每行字符数: 统计指定的文本中,每行数据的字符数量.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>// 获取文件总行数
int Get_File_Line(FILE *fp)
{if (fp == NULL) return -1;char buf[1024] = { 0 };int line = 0;while (fgets(buf, 1024, fp) != NULL){++line;}fseek(fp, 0, SEEK_SET);return line;
}// 输出每行中字符数量
void MyPrint(FILE *fp,char **ptr,int len)
{char buffer[2048] = { 0 };int index = 0;while (fgets(buffer, 2048, fp) != NULL){int cur_len = strlen(buffer) + 1; // 获取每行数据长度printf("文件行: %d --> 该行字符数: %d \n", index + 1, cur_len);index++;memset(buffer, 0, 2048);}
}int main(int argc, char * argv[])
{FILE *fp = fopen("c:/conf.ini", "r");int len = Get_File_Line(fp);char **ptr = malloc(sizeof(char *)* len);   // 分配行数取决于文件行数MyPrint(fp, ptr, len);                      // 输出每行中的字符数量system("pause");return 0;
}

实现文件加解密: 此处对二进制字符进行异或操作得到,第一次调用函数可加密,第二次调用函数实现解密.

#include <stdio.h>
#include <stdlib.h>int encrypt(char *src_file, char *dst_file, char *passwd)
{FILE *fp_src = fopen(src_file, "rb");FILE *fp_dst = fopen(dst_file, "wb");if (fp_src == NULL || fp_dst == NULL)return - 1;char ch;while (!feof(fp_src)){ch = fgetc(fp_src);if (feof(fp_src))break;ch = ch ^ *(passwd); // 使用密码对目标进行异或操作fputc(ch, fp_dst);   // 将字符串写入到目标文件中}fclose(fp_src);fclose(fp_dst);return 1;
}int main(int argc, char* argv[])
{int encode_ret = encrypt("c:/lyshark.log", "c:/encode.log", "1233");if (encode_ret == 1)printf("加密完成 \n");int decode_ret = encrypt("c:/encode.log", "c:/decode.log", "1233");if (decode_ret == 1)printf("解密完成 \n");system("pause");return 0;
}

实现格式化读写: 两个函数fprintf()/fscanf()分别实现对数据的格式化读取与格式化写入.

#include <stdio.h>struct Student
{int uid;char name[20];int age;
};void write()
{FILE *fp = fopen("c://lyshark.log", "wt+");struct Student stu[3] = {{ 1001, "admin", 22 },{ 1002, "guest", 33 },{ 1003, "uroot", 12 },};// 将数据格式化输出到文本中保存for (int x = 0; x < 3; x++)fprintf(fp, "%d %s %d \n", stu[x].uid, stu[x].name, stu[x].age);fclose(fp);
}void read()
{struct Student stu;FILE *fp = fopen("c://lyshark.log", "r");while (fscanf(fp, "%d %s %d \n", &stu.uid, &stu.name, &stu.age) != EOF){printf("UID: %d --> Name: %s --> Age: %d \n", stu.uid, stu.name, stu.age);}/* 此处的方法也可以实现while (fgets(buffer, 1024, fp) != NULL){sscanf(buffer,"%d %s %d \n", stu.uid, stu.name, stu.age);index++;}*/
}int main(int argc, char* argv[])
{write();read();system("pause");return 0;
}

实现结构随机读写: 我们可以通过文件操作将结果数据写入文件,然后通过fseek()移动指针来遍历结构数据.

#include <stdio.h>struct Student
{int uid;char name[20];int age;
};void Write()
{struct Student stu[3] = {{ 1001, "admin", 22 },{ 1002, "guest", 33 },{ 1003, "uroot", 12 },};FILE *fp = fopen("c://lyshark.log", "wb+");/* 第一种写入文本的方式for (int x = 0; x < 3; x++)fprintf(fp, "%d %s %d \n", stu[x].uid, stu[x].name, stu[x].age);fclose(fp);*/// 随机读写fwrite(stu, sizeof(struct Student), 3, fp);   // 写入三条数据fclose(fp);
}int main(int argc, char* argv[])
{Write();    // 调用函数,写入测试数据struct Student p;FILE *fp = fopen("c://lyshark.log", "rb+");fseek(fp, sizeof(struct Student), SEEK_SET);        // 移动文件指针,到下一个结构fread(&p, sizeof(struct Student), 1, fp);           // 读取数据printf("UID: %d ---> Name: %s \n", p.uid, p.name);  // 输出读取到的数据fread(&p, sizeof(struct Student), 1, fp++);         // 读取下一个数据printf("UID: %d ---> Name: %s \n", p.uid, p.name);  // 输出读取到的数据system("pause");return 0;
}

实现数组块读写: 将数组通过文件写入到磁盘中保存,然后再从磁盘中将其取出来.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>int main(int argc, char* argv[])
{int Array[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };// 将数组写入到文件中保存FILE *write = fopen("c://list.log", "wb");fwrite(Array, sizeof(int), 10, write);fclose(write);// -----------------------------------------------// 从文件中读取数组元素FILE *read = fopen("c://list.log", "rb");int NewArray[10] = { 0 };int index = 0;while (!feof(read)){   // 将数据逐个读取到数组中存储.fread(&NewArray[index], sizeof(int), 1, read);index++;}fclose(read);// 循环打印出数组元素for (int x = 0; x < 10; x++)printf("%d \n", NewArray[x]);system("pause");return 0;
}

实现结构块读写: 在定义结构块的时候,不应使用指针变量,因为指正无法被转储到文件中.

#include <stdio.h>
#include <stdlib.h>struct Student
{int uid;char name[30];int age;
};// 保存结构到文件中
int Save_Struct(struct Student *ptr, int len)
{FILE *fp = fopen("c:/save.log", "wb");if (fp == NULL)return -1;for (int x = 0; x < len; x++){fwrite(&ptr[x], sizeof(struct Student), 1, fp);}fclose(fp);return 0;
}// 从文件中加载结构
int Load_Struct(struct Student *ptr)
{FILE *fp = fopen("c:/save.log", "rb");if (fp == NULL)return -1;int index = 0;while (!feof(fp)){fread(&ptr[index], sizeof(struct Student), 1, fp);index++;}fclose(fp);return 0;
}int main(int argc, char* argv[])
{struct Student stu[3] = {{ 1001, "admin", 22 },{ 1002, "guest", 33 },{ 1003, "root", 12 },};Save_Struct(&stu, 3);  // 保存文件// 将输入读取到read_stu结构中struct Student read_stu[3];Load_Struct(&read_stu);for (int x = 0; x < 3; x++)printf("UID: %d --> Name: %s --> Age: %d \n", read_stu[x].uid, read_stu[x].name, read_stu[x].age);system("pause");return 0;
}

针对文件内容的排序: 首先将文件格式化读取到堆中,然后排序,排序完成以后再次会写到文件中.

#include <stdio.h>
#include <stdlib.h>
#include <time.h>// 先来生成一些测试数据
void Random()
{srand((unsigned int)time(NULL));FILE *fp = fopen("c:/lyshark.log", "w");if (!fp)return -1;for (int x = 0; x < 10000; x++){fprintf(fp, "%d\n", rand() % 1000 + 1);}fcloseall();
}int main(int argc, char * argv[])
{FILE *fp = fopen("c:/lyshark.log", "r");if (!fp)return -1;// 动态的分配堆空间,此处分配10000个int空间int *ptr = (int *)malloc(sizeof(int)* 10000);// 读取数据,并动态放入堆空间中.for (int x = 0; x < 10000; x++)fscanf(fp, "%d\n", &ptr[x]);// 使用冒泡排序,对堆空间进行排序for (int x = 0; x < 10000; x++){for (int y = 0; y < 10000 - x - 1; y++){if (ptr[y] > ptr[y + 1]){int tmp = ptr[y];ptr[y] = ptr[y + 1];ptr[y + 1] = tmp;}}}fcloseall();// 排序完成后,开始写入数据FILE *fp1 = fopen("c:/lyshark.log", "w");if (!fp1)return -1;for (int x = 0; x < 10000; x++)fprintf(fp1, "%d\n", ptr[x]);fcloseall();free(ptr);system("pause");return 0;
}

实现配置文件解析: 这里我们定义一个配置文件,格式为username:root,然后通过编程实现遍历指定的key=value键值对.

#include <stdio.h>
#include <stdlib.h>// 配置文件数组
struct ConfigInfo
{char key[64];char val[128];
};// 判断数据是否符合规则
int isvald(const char *buf)
{if (buf[0] == '#' || buf[0] == '\n' || strchr(buf, ':') == NULL)return 0;return 1;
}// 获取有效行
int get_line(FILE *fp)
{char buffer[1024] = { 0 };int index = 0;while (fgets(buffer, 1024, fp) != NULL){if (!isvald(buffer))continue;memset(buffer, 0, 1024);index++;}fseek(fp, 0, SEEK_SET);return index;
}// 加载有效行,到内存栈地址
void load(const char *path, char **data, int *len)
{FILE *fp = fopen(path, "r");int line = get_line(fp);      // 获取有效行char **tmp = malloc(sizeof(char *)* line);   // 给每行开辟空间char buf[1024] = { 0 };int index = 0;while (fgets(buf, 1024, fp) != NULL){if (!isvald(buf))continue;tmp[index] = malloc(strlen(buf) + 1);strcpy(tmp[index], buf);memset(buf, 0, 1024);++index;}*data = tmp;  // 返回结构数据*len = line;  // 返回有效行数fcloseall();
}// 解析配置文件,data = 结构数据 len = 结构数量 key = 待查找字符串
char * parser(char **data, int len, struct ConfigInfo **info, char *key)
{struct ConfigInfo *tmp = malloc(sizeof(struct ConfigInfo) * len);memset(tmp, 0, sizeof(struct ConfigInfo) * len);for (int x = 0; x < len; x++){char *pos = strchr(data[x], ':');strncpy(tmp[x].key, data[x], pos - data[x]);     // 拷贝keystrncpy(tmp[x].val, pos + 1, strlen(pos + 1) - 1);   // 拷贝valprintf("key: %s --> val: %s \n", tmp[x].key, tmp[x].val);// 判断如果我们要找的key = my[x].key 则找到了,直接返回if (strcmp(key, tmp[x].key) == 0)return tmp[x].val;}// 释放文件for (int y = 0; y < len; ++y){if (data[y] != NULL)free(data[y]);}
}int main(int argc, char * argv[])
{char *data = NULL;struct ConfigInfo *info = NULL;int lines = 0;load("c:/conf.ini", &data, &lines);char * username = parser(data, lines, &info, "username");printf("读取到 username 变量中的值: %s \n", username);char * password = parser(data, lines, &info, "password");printf("读取到 password 变量中的值: %s \n", password);system("pause");return 0;
}

本文作者: 王瑞
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

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

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

相关文章

ubuntu安装Miniconda并举例使用

更新系统包 sudo apt update sudo apt upgrade官网下载Miniconda&#xff0c;最好是实体机下载后放进虚拟机&#xff0c;方法可以参考Xftp 7连接服务器或者本地虚拟机文章 https://docs.conda.io/en/latest/miniconda.html#linux-installers 进入安装目录执行&#xff0c;右键…

Maven 引入外部依赖

如果我们需要引入第三方库文件到项目&#xff0c;该怎么操作呢&#xff1f; pom.xml 的 dependencies 列表列出了我们的项目需要构建的所有外部依赖项。 要添加依赖项&#xff0c;我们一般是先在 src 文件夹下添加 lib 文件夹&#xff0c;然后将你工程需要的 jar 文件复制到 …

[MT8766][Android12] 使用谷歌LPA实现ESIM功能的流程

文章目录 开发平台基本信息问题描述实现流程 其他问题 开发平台基本信息 芯片: MT8766 版本: Android 12 kernel: msm-4.19 问题描述 客户需要我们设备支持ESIM功能&#xff0c;5月份的时候在高通6125上面预研过ESIM功能&#xff0c;当时ESIM供应商是Links field&#xff0c…

OpenCV4(C++)—— 视频和摄像头的加载、显示与保存

文章目录 一、加载与显示二、保存 一、加载与显示 视频或摄像头的加载是使用 cv::VideoCapture 类。&#xff08;这个类和 ifstream 类比较相似&#xff0c;视频或摄像头的加载和文本文件操作是大致相同。主要步骤&#xff1a;&#xff08;1&#xff09;加载&#xff08;打开&a…

Springboot接收http参数总结(最简单易懂)

1. 前端能携带请求参数的地方 http请求一半前端请求参数放在三个地方&#xff1a;请求头&#xff0c;请求查询参数&#xff08;Query String&#xff09;&#xff0c;请求体。 请求体需要获取HttpServletRequest对象才能获取。 2. 请求体常见格式 而请求体中可以存放多种格式…

深度学习-房价预测案例

1. 实现几个函数方便下载数据 import hashlib import os import tarfile import zipfile import requests#save DATA_HUB dict() DATA_URL http://d2l-data.s3-accelerate.amazonaws.com/def download(name, cache_diros.path.join(.., data)): #save"""下载…

架构师选择题--信息安全技术(系统安全)

架构师选择题--信息安全技术 真题 很少超纲 真题 b c d d b a d a d a Kergberos和数字证书是类似的协议 向TGS申请票据 C PGP&#xff1a;安全电子邮件传输协议 b c b 使用发送方是私钥加密摘要–发送方不可抵赖 加密&#xff1a;保密性 信息摘要&#xff1a;完整性 数…

闭包(C#)

通常来讲&#xff0c;大家一听到闭包&#xff0c;应该首先会想到JavaScript中的闭包&#xff0c;而不会想到C#中的闭包&#xff0c;但是C#中也是有闭包的&#xff0c;下面就让我来为大家仔细讲解讲解。 在C#中&#xff0c;我们通常知道变量作用域有三种&#xff1a;1、是属于类…

docker compose和consul(服务注册与发现)

一、Docker-compose 简介 Docker-Compose项目是基于Python开发的Docker官方开源项目&#xff0c;负责实现对Docker容器集群的快速编排。 Docker-Compose将所管理的容器分为三层&#xff0c;分别是 工程&#xff08;project&#xff09;&#xff0c;服务&#xff08;service&a…

登录页面怎么做渗透

1.用万能密码登录&#xff0c;看是否能登录成功 ‘ or 11# 2.注入漏洞 用burp抓包放在sqlmap里面跑&#xff0c;看是否有注入 3.查看是否有说明文档找文件下载漏洞 一般的链接形式 download.php?path download.php?filename down.php?file data.php?file 包含的参数 &…

Mabatis-puls强于Mybatis的地方

Mabatis-puls与Mybatis都是优秀的Java持久化框架&#xff0c;但是Mabatis-puls相较于Mybatis有以下几个方面的优势&#xff1a; 性能更优&#xff1a;Mabatis-puls采用了Javassist技术&#xff0c;使得它在运行时比Mybatis更快速&#xff0c;尤其是在执行大量SQL的情况下&#…

TensorFlow入门(二十一、softmax算法与损失函数)

在实际使用softmax计算loss时,有一些关键地方与具体用法需要注意: 交叉熵是十分常用的,且在TensorFlow中被封装成了多个版本。多版本中,有的公式里直接带了交叉熵,有的需要自己单独手写公式求出。如果区分不清楚,在构建模型时,一旦出现问题将很难分析是模型的问题还是交叉熵的使…

代码随想录算法训练营第23期day19| 654.最大二叉树、617.合并二叉树、700.二叉搜索树中的搜索、98.验证二叉搜索树

目录 一、&#xff08;leetcode 654&#xff09;最大二叉树 二、&#xff08;leetcode 617&#xff09;合并二叉树 三、&#xff08;leetcode 700&#xff09;二叉搜索树中的搜索 四、&#xff08;leetcode 98&#xff09;验证二叉搜索树 一、&#xff08;leetcode 654&…

Vega Prime入门教程14.01:调用VAPS XT DLL

本文首发于&#xff1a;Vega Prime入门教程14.01&#xff1a;调用VAPS XT DLL 在VAPS XT系列教程中提到过Vega Prime可以直接调用Drawing Integration生成的dll&#xff0c;本文来测试这个功能效果。 本系列使用的是VP18.0&#xff0c;使用的是VC14.0&#xff08;VS2015&…

Android Studio修改模拟器AVD Manger目录

Android Studio修改虚拟机AVD Manger目录 1、在AS的设备管理器Device Manager中删除原来创建的所有虚拟机&#xff08;Android Virtual Device&#xff09;&#xff1b; 2、新建一个自定义的AVD目录&#xff0c;例如&#xff1a;D:\Android\AndroidAVD 3、在高级系统设置中增加…

hive建表指定列分隔符为多字符分隔符实战(默认只支持单字符)

1、背景&#xff1a; 后端日志采集完成&#xff0c;清洗入hive表的过程中&#xff0c;发现字段之间的单一字符的分割符号已经不能满足列分割需求&#xff0c;因为字段值本身可能包含分隔符。所以列分隔符使用多个字符列分隔符迫在眉睫。 hive在建表时&#xff0c;通常使用ROW …

【Zookeeper专题】Zookeeper选举Leader源码解析

目录 前言阅读建议课程内容一、ZK Leader选举流程回顾二、源码流程图三、Leader选举模型图 学习总结 前言 为什么要看源码&#xff1f;说实在博主之前看Spring源码之前没想过这个问题。因为我在看之前就曾听闻大佬们说过【JavaCoder三板斧&#xff1a;Java&#xff0c;Mysql&a…

Arduino驱动LIS2DH三轴加速度传感器(惯性测量传感器篇)

目录 1、传感器特性 2、硬件原理图 3、控制器和传感器连线图 4、驱动程序 LIS2DH加速度计相对传统的ADXL345在稳定性以及功耗上都有一定的优化,低功耗模式下仅为2μA(普通模式11μA),并且最高支持5.3KHz输出频率,拥有2g/4g/8g/16g四档可选量程&

Kafka和RabbitMQ的对比

Rabbitmq比kafka可靠&#xff0c;kafka更适合IO高吞吐的处理&#xff0c;比如ELK日志收集 Kafka和RabbitMq一样是通用意图消息代理&#xff0c;他们都是以分布式部署为目的。但是他们对消息语义模型的定义的假设是非常不同的。 a) 以下场景比较适合使用Kafka。如果有大量的事…

程序员不写注释的原因及解决方案

目录 一、原因说明 二、问题分析 三、解决方案 在软件开发领域&#xff0c;注释的重要性不言而喻。它们不仅可以提高代码的可读性&#xff0c;还能帮助其他开发者更好地理解代码逻辑。然而&#xff0c;我们常常发现许多程序员在编写代码时并不喜欢添加注释。那么&#xff0c…