【C语言】文件操作(1)(文件打开关闭和顺序读写函数的万字笔记)

在这里插入图片描述

文章目录

  • 一、什么是文件
    • 1.程序文件
    • 2.数据文件
  • 二、数据文件
    • 1.文件名
    • 2.数据文件的分类
      • 文本文件
      • 二进制文件
  • 三、文件的打开和关闭
    • 1.流和标准流
      • 标准流
    • 2.文件指针
    • 3.文件的打开和关闭
      • 文件的打开
      • 文件的关闭
  • 四、文件的顺序读写
    • 1.fgetc函数
    • 2.fputc函数
    • 3.fgets函数
    • 4.fputs函数
    • 5.fscanf函数
    • 6.fprintf函数
    • 7.fwrite函数
    • 8.fread函数

一、什么是文件

   我们写的程序的数据是存储在电脑的内存中,如果程序退出,内存回收,数据就丢失了,等再次运⾏程序,是看不到上次程序的数据的,如果要将数据进⾏持久化的保存,我们可以使⽤⽂件
   文件是计算机系统中的一个基本概念,它是存储在计算机上的信息集合,可以是文本文档、图片、程序等,但是在程序设计中,我们⼀般谈的⽂件有两种:程序⽂件、数据⽂件(从⽂件功能的⻆度来分类的)

1.程序文件

   程序⽂件包括源程序⽂件(后缀为.c),⽬标⽂件(windows环境后缀为.obj),可执⾏程序(windows环境后缀为.exe)

2.数据文件

   文件的内容不⼀定是程序,而是程序运行时读写的数据,比如程序运⾏需要从中读取数据的⽂件,或者输出内容的⽂件

二、数据文件

   本文着重讨论的是数据文件,在以前我们学的知识中,所处理的数据的输⼊都是以键盘输⼊数据,用显示器输出
   但是我们之前的程序结果输出到显示器后,结束程序,这个结果不会被保存,那是因为我们运行程序时,把数据放在了内存,程序结束后,内存回收了,数据也就没了
   那我们很多情况下想把数据永久保存起来,就要使用磁盘上的数据文件存储起来,存储到磁盘的数据就会一直保存,当需要使用数据时,就从数据文件中将数据读入到我们的内存进行操作,本文将会讲解的就是操作数据文件

1.文件名

   ⼀个⽂件要有⼀个唯⼀的⽂件标识,以便⽤⼾识别和引⽤,这个文件标识就是我们常说的文件名,⽂件名包含3部分:⽂件路径+⽂件名主⼲+⽂件后缀

例如: c:\code\test.txt

   在这个例子中,文件的路径就是c:\code\,文件名的主干就是test,文件后缀是.txt,说明这个文件是一个文本文件,属于数据文件之一
   而路径又可以分为相对路径和绝对路径,上面演示的就是绝对路径,如果对这个有兴趣的话,可以自行搜索文章学习,这里我们还是继续进行我们的文件操作的学习

2.数据文件的分类

   根据数据的组织形式,数据⽂件被称为⽂本⽂件或者⼆进制⽂件

文本文件

   如果要求在外存上以ASCII码的形式存储,则需要在存储前转换,以ASCII字符的形式存储的⽂件就是⽂本⽂件
   简单的理解就是,如果打开这个文件你可以看懂上面的信息,那么就是文本文件,例如汉字,英文字母等等信息,文本文件常见的后缀为:.txt 和 .docx 以及 .rtf

二进制文件

   数据在内存中以⼆进制的形式存储,如果不加转换的输出到外存的⽂件中,就是⼆进制⽂件,由于里面是0和1序列组成的二进制,然后转换出来的字符,所以根本看不懂里面的内容
   我们可以在VS运行下面的代码,如果不懂也没有关系,后面会讲到,这里只是举一个例子:

#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>
int main()
{int a = 10000;//以二进制写的方式打开FILE* pf = fopen("test.txt", "wb");if (pf == NULL){perror(fopen);return 1;}//⼆进制的形式写到⽂件中fwrite(&a, 4, 1, pf);//关闭文件fclose(pf);pf = NULL;return 0;
}

   我们运行它之后会发现当前代码路径下会多出一个test.txt的文件,打开当前代码路径的方法是单击左上角文件夹图标,如图:
在这里插入图片描述
   然后我们双击打开这个文件:
在这里插入图片描述
   可以看到我们明明是将10000写入到了这个文件中,但是最后我们打开文件后发现是一个我们看不懂的字符,原因就是我们写入时,是以二进制的写入方式打开文件的,里面存储的是二进制的信息

三、文件的打开和关闭

1.流和标准流

   我们程序的数据需要输出到各种外部设备,也需要从外部设备获取数据,不同的外部设备的输⼊输出操作各不相同,为了⽅便程序员对各种设备进行方便的操作,我们抽象出了流的概念,我们可以把流想象成流淌着字符的河
   比如向文件里输入信息和向屏幕输入信息的方式不同,但是程序员不必了解它们如何输入的,程序员只需要去往对应的流写入或读出操作,不需要担心各种设备的输入输出操作
   ⼀般情况下,我们要想向流⾥写数据,或者从流中读取数据,都是要打开流,然后操作,打开流的方法我们后面会讲到

标准流

   刚刚提到了,如果要输入或者读取信息,都要打开流,然后进行操作,那么每次我们在键盘输入信息,在屏幕上打印信息为什么没有专门打开流呢?那是因为C语言程序在启动时,默认打开了3个标准流:

  • stdin - 标准输⼊流,在⼤多数的环境中从键盘输⼊,scanf函数就是从标准输⼊流中读取数据
  • stdout - 标准输出流,⼤多数的环境中输出⾄显⽰器界⾯,printf函数就是将信息输出到标准输出流中
  • stderr - 标准错误流,⼤多数环境中输出到显⽰器界⾯

   这是默认打开的三个标准流,我们使⽤scanf、printf等函数就可以直接进⾏输⼊输出操作的,它们的类型是FILE*的指针,通常称为文件指针,对文件的操作就是使用文件指针进行操作

2.文件指针

   缓冲⽂件系统中,关键的概念是“⽂件类型指针”,简称“⽂件指针”,每个被使⽤的⽂件都在内存中开辟了⼀个相应的⽂件信息区,⽤来存放⽂件的相关信息(如⽂件的名字,⽂件状态及⽂件当前的位置等)
   这些信息是保存在⼀个结构体变量中的,该结构体类型是由系统声明的,这个结构体就叫FILE,我们可以在VS2013编译环境提供的 stdio.h 头⽂件中有以下的⽂件类型申明:

struct _iobuf {char* _ptr;int _cnt;char* _base;int _flag;int _file;int _charbuf;int _bufsiz;char* _tmpfname;
};typedef struct _iobuf FILE;

   不同的C编译器的FILE类型包含的内容不完全相同,但是⼤同⼩异,每当打开⼀个⽂件的时候,系统会根据⽂件的情况⾃动创建⼀个FILE结构的变量,并填充其中的信
息,使⽤者不必关⼼细节
   C语言⼀般都是通过⼀个FILE的指针来维护这个FILE结构的变量,这样使⽤起来更加⽅便,下面我们可以创建一个文件指针变量:

FILE* pf;//⽂件指针变量

   这里定义的pf是⼀个指向FILE类型数据的指针变量,可以使pf指向某个⽂件的⽂件信息区(⼀个结构体),通过该⽂件信息区中的信息就能够访问该⽂件。也就是说,通过⽂件指针变量能够间接找到与它关联的⽂件,如图:
在这里插入图片描述

3.文件的打开和关闭

   ⽂件在读写之前应该先打开⽂件,在使⽤结束之后应该关闭⽂件,现在我们就来学习如何打开和关闭文件
   ANSI C 规定使⽤ fopen 函数来打开⽂件, fclose 来关闭⽂件,在打开⽂件的同时,它们都会返回⼀个FILE*的指针变量指向该⽂件,也相当于建⽴了指针和⽂件的关系

文件的打开

   我们来看看打开文件的函数fclose的原型:

FILE * fopen ( const char * filename, const char * mode );

   如果文件打开成功了,那么就会返回一个FILE*的指针,我们可以用一个文件指针变量接收,然后我们后续就可以通过这个文件指针变量对这个文件进行操作
   如果文件打开失败了,那么就会返回一个空指针NULL,所以我们在使用fopen后,最好再判断一下它的返回值是否是空指针,如果是空指针说明文件打开失败,直接返回
   它的参数有两个,第一个是我们要打开的文件的名字,第二个参数是我们打开文件的方式,是以读的方式,还是写的方式,还是读写等等方式,如下图:
在这里插入图片描述
   在上图中展示了文件打开的方式,以及如果文件不存在,会做出什么操作,现在我们还没有讲解怎么对文件进行读写,所以有点懵也没有关系,在后面的读写部分都会讲解,这里只了解一下
   接下来我们来试着写一个代码,以只读的方式打开一个文本文件test.txt,如下:

	FILE* pf = fopen("test.txt", "r");//打开文件//判断是否打开成功,打开失败就返回错误信息并返回:if (pf == NULL){perror("fopen");return 1;}

   这样我们就打开了文件了,至于读写操作我们后面讲,现在先来看看如何关闭文件

文件的关闭

   我们来看看关闭文件的函数fclose的原型:

int fclose ( FILE * stream );

   它的返回值是int类型,如果文件关闭成功就返回0,如果文件关闭失败就返回EOF
它的参数是我们要关闭的流,在这里我们要关闭文件,就把文件的流,也就是对应的文件指针变量传过来
   我们要注意的是,关闭文件后,pf这个指针变量就指向野指针了,所以最好关闭文件后将其置为空指针NULL,我们来看看关闭文件关闭的过程:

//关闭⽂件
int fclose (pf);
//为了防止pf成为野指针,可以把它置为空指针
pf = NULL;

   这就是我们关闭文件的过程,接下来我们就学习最关键的文件读写操作

四、文件的顺序读写

   文件的顺序读写就是按照文件数据从头到尾进行读写,读写操作也是由我们的函数来完成的,如下表:
在这里插入图片描述
   我们接下来就就一一讲解这些函数:

1.fgetc函数

   我们要学习的第一个函数是fgetc,它的作用就是从流中获取一个字符,不是应该属于输出吗?那么为什么在表中它叫字符输入函数呢?
   这是我们要注意的一点,我们说的输入输出是站在内存的角度思考的,我们从流里面获取了一个字符,对流来说,也就是对文件来说是输出,但是如果站在内存角度思考就会发现,获取的字符存储到内存中了,应该是属于输入,所以我们说的输入输出都是基于内存角度的
   实在不理解也没什么,我们掌握它的用法就行,我们来看看它的原型:

int fgetc ( FILE * stream );

   它的参数就是我们要从哪个流里面获取一个字符,在这里我们要操作文件,很明显就是从文件流里面获取字符,所以需要填一个文件指针变量进去
   它的返回值是整型,如果成功从文件中读取了一个字符,那么就返回这个字符的Ascll码值,如果读取失败或者读取到了文件末尾,那么就返回EOF,现在我们就来使用一下它
   我们首先明确一下条件,在当前代码路径下有一个test.txt的文件,里面的内容是hello world!,然后我们开始写代码,由于这是第一遍,所以我来带大家实现一下全过程,后面文件的打开和关闭就不会再讲解了
   首先我们要以读的形式打开文件,然后用文件指针变量接收,判断返回值是否为空,如下:

#include <stdio.h>int main()
{FILE* pf = fopen("test.txt", "r");if (pf == NULL){perror("fopen");return 1;}return 0;
}

   随后我们就开始使用fgetc函数来实现读取操作,用一个字符变量ch来接收它的返回值,然后打印ch,如下:

	char ch = fgetc(pf);printf("%c\n", ch);

   随后就是最后一步:关闭文件,注意关闭文件后要把pf置为空指针,如下:

fclose(pf);
pf = NULL;

   完整代码:

#include <stdio.h>int main()
{FILE* pf = fopen("test.txt", "r");if (pf == NULL){perror("fopen");return 1;}char ch = fgetc(pf);printf("%c\n", ch);fclose(pf);pf = NULL;return 0;
}

   最后我们来运行一下代码:
在这里插入图片描述
   可以看到我们成功读取了一个字符h,那么问题来了,如果我想将文件中的字符全部读出来怎么办呢?我们也不是每一次都知道文件中有多少个字符
   这个时候我们可以利用fgetc的返回值,创建一个while循环,只要fgetc的返回值不是EOF就一直循环,每次循环把读取到的字符打印出来,直到将所有字符读取完毕返回EOF结束循环,如下:

	char ch = 0;while ((ch = fgetc(pf)) != EOF){printf("%c", ch);}

   接着我们再次运行程序试试:
在这里插入图片描述
   可以看到这里就把文件中的所有字符都读出来了

2.fputc函数

   fgetc函数和fputc函数很相似,只是fgetc是将一个字符从流中读出,而fputc的作用是将一个字符写入到文件中,我们来看看它的原型:

int fputc ( int character, FILE * stream );

   它的第一个参数就是我们要写入的字符,第二个参数就是我们的流,我们操作文件,所以要写文件流
   如果写入成功,那么它的返回值就是这个字符的Ascll码值,如果失败就返回EOF,当然,它的返回值我们很少用到
   接着我们就使用一下这个函数,这里要强调的一点是,以写的方式打开文件,第一步会清空文件中的内容,然后再进行写的操作,如果不想文件中的内容被清楚,可以使用追加的方式打开
   我们这里就可以使用写的方式打开test.txt文件,让它将里面的hello world!删除了,然后我们再使用fputc来写入一个字符,如下:

#include <stdio.h>int main()
{FILE* pf = fopen("test.txt", "w");if (pf == NULL){perror("fopen");return 1;}char ch = 0;fputc('x', pf);fclose(pf);pf = NULL;return 0;
}

   运行代码后屏幕上没有出现任何信息,接着我们就来看看test.txt文件有没有按预期被修改,如图:
在这里插入图片描述
   可以看到,hello world!已经被清除了,并且字符x已经被我们写入到文件了

3.fgets函数

   fgets函数的作用是从文件中读出一行的信息,我们来看看它的原型:

char * fgets ( char * str, int num, FILE * stream );

   它的第一个参数就是我们要把读出的一行数据放入哪个字符串,第二个参数就是我们要读出几个字符,最后一个参数就是要从哪个流中读取数据
   如果读取成功,那么它的返回值就是从文件中读取出的第一行的字符串的首地址,可以使用%s的形式打印出来,如果读取失败,则会返回空指针NULL
   接着就让我们使用一下这个函数,首先明确前提,当前目录下有一个test.txt的文件,里面的内容有两行,第一行是hello,第二行是world!,我们来读取它的第一行,然后把它的第一行内容打印出来:

	char arr[20] = { 0 };fgets(arr, 20, pf);printf("%s\n", arr);

   完整代码:

#include <stdio.h>int main()
{FILE* pf = fopen("test.txt", "r");if (pf == NULL){perror("fopen");return 1;}char arr[20] = { 0 };fgets(arr, 20, pf);printf("%s\n", arr);fclose(pf);pf = NULL;return 0;
}

   我们来看看代码运行截图:
在这里插入图片描述
   还是同样的问题,如果我想将文件的所有行都读出来呢?虽然我们现在知道有两行数据,可以只调用两次fgets函数,但是万一下次遇到很多行数据呢?
   所以这里我们还是要利用它的返回值,创建一个while循环,如果fgets没有返回空指针,说明读取到了一行信息,那么我们就把它打印出来,如果返回空指针就结束循环,如下:

	char arr[20] = { 0 };while (fgets(arr, 20, pf)){printf("%s", arr);}

   我们来看看代码运行结果:
在这里插入图片描述
   可以看到代码自动把所有行打印出来了

4.fputs函数

   fgets函数和fputc函数很相似,只是fgets是将一行字符从流中读出,而fputs的作用是将一行字符写入到文件中,我们来看看它的原型:

int fputs ( const char * str, FILE * stream );

   这个函数的第一个参数就是我们要写入的字符串,第二个参数就是要写入的流
如果文件写入成功,那么就返回一个非零的值,如果写入失败就返回EOF
   接着我们就来使用fputs向文件test.txt写入一行字符hello world!,如下:

	char arr[20] = "hello world!";fputs(arr, pf);

   完整代码:

#include <stdio.h>int main()
{FILE* pf = fopen("test.txt", "w");if (pf == NULL){perror("fopen");return 1;}char arr[20] = "hello world!";fputs(arr, pf);fclose(pf);pf = NULL;return 0;
}

   然后我们运行代码后来看看test.txt有没有被写入这一行信息:
在这里插入图片描述
   可以看到文件里已经成功写入了一行信息

5.fscanf函数

   fscanf是以格式化的方式对文件进行读取操作,它与scanf函数的使用方法相似,它们的区别就是fscanf的第一个参数是流,后面和scanf的参数一样,我们来对比一下scanf和fscanf的原型:

//scanf的原型:
int scanf ( const char * format, ... );
//fscanf的原型:
int fscanf ( FILE * stream, const char * format, ... );

   可以看到它们的区别就是fscanf多一个流的选择,它们的返回值也是一样的,都是返回成功读取的项目的个数,如果读取失败返回EOF,如果还不熟悉scanf可以参考文章:
【C语言】printf和scanf函数详解
   我们这里也可以顺便说一下它们之间的关系,scanf是从标准输入流读取数据,而fscanf可以从任何流中读取数据,那么fscanf也必然可以从标准输入流读取数据,此时它们的作用就是一致,我们在上面也说过标准输入流是stdin,我们将fscanf的第一个参数写成标准输入流stdin就可以了,如下:

fscanf (stdin , const char * format, ... );
//等价于scanf

   说明了它们的关系,我们就来示例使用一下fscanf,我们的前提条件是:当前文件夹下有一个test.txt文件,里面包含的数据有:123 hello,现在我们要以格式话的方式将它们读取出来,也就是将123读取为整型,hello读取为字符串
   首先我们要创建一个整型变量和一个字符数组,用来存储我们读取到的信息,然后将它们打印出来,代码如下:

	int i = 0;char arr[20] = { 0 };fscanf(pf, "%d %s", &i, arr);printf("%d %s", i, arr);

   可以看到fscanf和scanf确实只有第一个参数的不同,接着我们来看看完整的代码:

#include <stdio.h>int main()
{FILE* pf = fopen("test.txt", "r");if (pf == NULL){perror("fopen");return 1;}int i = 0;char arr[20] = { 0 };fscanf(pf, "%d %s", &i, arr);printf("%d %s", i, arr);fclose(pf);pf = NULL;return 0;
}

   我们来看看代码运行结果:
在这里插入图片描述

6.fprintf函数

   fprintf函数和printf函数又非常相似,也是第一个参数不同,其它的使用方法一致,fprintf的原型如下:

int fprintf ( FILE * stream, const char * format, ... );

   它的返回值就不说了,与printf一致,不知道的可以看上面的链接,有printf的详细使用教程,它的参数也只是比printf多一个
   它们只是作用不同,fprintff的作用是向所有流中写入数据,而printf是向标准输出流写入数据,fprintf要全面一些,当fprintf的第一个参数是标准输出流stdout的时候,它的作用就和printf相同了,如下:

fprintf(stdout, const char * format, ... )
//等价于printf

   说完它们的关系我们就回到正题,来使用一下fprintf函数对文件test.txt写入一些格式化的数据,比如写入字符串world和浮点型的3.14,如下:

float f = 3.14f;
char arr[20] = "world";
fprintf(pf, "%s %f", arr, f);

   完整代码如下:

#include <stdio.h>int main()
{FILE* pf = fopen("test.txt", "w");if (pf == NULL){perror("fopen");return 1;}float f = 3.14f;char arr[20] = "world";fprintf(pf, "%s %f", arr, f);fclose(pf);pf = NULL;return 0;
}

   接着我们运行代码来看看文件test.txt有没有被修改,如下:
在这里插入图片描述
   可以看到文件被成功写入了格式化的数据

7.fwrite函数

   我们要讲的最后两个函数fread和fwrite与上面讲的函数不同,上面的函数都是对文件写入或读取我们看得懂的文本信息,而这两个函数是对文件写入或读取二进制信息
   也就是对二进制文件进行操作,所以打开文件时要使用rb或者wb的方式,我们首先来看看fwrite函数,它是向文件写入二进制的信息,它的原型如下:

size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );

   它的第一个参数是我们要写入的信息的首地址,第二个参数size就是我们要写入的信息的一个元素的大小,第三个参数count是我们要写入的元素的个数,最后一个参数就是我们要往哪个流写入信息
   它的返回值就是被成功写入文件的元素个数
   接着我们就赶紧去使用一下fwrite为test.txt文件写入一些二进制信息,我们要写的就是整型1到5,我们可以使用数组的方式,如下:

int arr[] = { 1,2,3,4,5 };
fwrite(arr, sizeof(arr[0]), 5, pf);

   然后我们来看看完整代码:

#include <stdio.h>int main()
{FILE* pf = fopen("test.txt", "wb");//二进制写的方式打开if (pf == NULL){perror("fopen");return 1;}int arr[] = { 1,2,3,4,5 };fwrite(arr, sizeof(arr[0]), 5, pf);fclose(pf);pf = NULL;return 0;
}

   然后我们来运行一下代码,看看test.txt文件有没有发生改变:
在这里插入图片描述
   可以看到test.txt文件被写入了一些二进制信息,但是我们看不出来是什么,也就不知道里面是不是装的我们写入的整型1到5,所以我们接下来学习对二进制文件信息进行读取的函数fread

8.fread函数

   fread函数的作用就是从文件中读取二进制的信息,刚好和fwrite搭配使用,我们来看看它的原型:

size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );

   可以看到它的参数和返回值都和fwrite差不多,没错,它们的原型的含义基本一致,这里就不多讲了
   在刚刚使用了fwrite向文件写入了整型1到5后,我们看不出来文件中的内容是否正确,现在我们就使用fread将里面的信息读取出来,看看是否是整型1到5,如下:

	int arr[5] = { 0 };fread(arr, sizeof(int), 5, pf);for (int i = 0; i < 5; i++){printf("%d ", arr[i]);}

   完整代码:

#include <stdio.h>int main()
{FILE* pf = fopen("test.txt", "rb");if (pf == NULL){perror("fopen");return 1;}int arr[5] = { 0 };fread(arr, sizeof(int), 5, pf);for (int i = 0; i < 5; i++){printf("%d ", arr[i]);}fclose(pf);pf = NULL;return 0;
}

   我们来运行代码看看fread帮我们从test.txt读出的信息是否是整型1到5:
在这里插入图片描述
   可以看到成功打印出来了整型1到5,从这里也验证了之前我们的fwrite使用正确了

   今天的分享就到这里结束啦,虽然只是文件操作的一部分,但是还是有一万字,基本上讲完了我们在读写时使用的函数,但是还是没有把文件操作部分要掌握的内容完全讲完
   所以文件操作还有下一篇文章,uu们敬请期待~
   那么今天说到这里,bye~

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

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

相关文章

微信小程序上传组件封装uploadHelper2.0使用整理

一、uploadHelper2.0使用步骤说明 uploadHelper.js ---上传代码封装库 cos-wx-sdk-v5.min.js---腾讯云&#xff0c;对象存储封装库 第一步&#xff0c;下载组件代码&#xff0c;放置到自己的小程序项目中 第二步、 创建上传对象&#xff0c;执行选择图片/视频 var _this th…

npm install进度卡在 idealTree:node_global: sill idealTree buildDeps

ping一下源&#xff1a;ping http://registry.npm.taobao.org/ ping不通&#xff0c;原因&#xff1a;原淘宝npm永久停止服务&#xff0c;已更新新域名~~震惊&#xff01;&#xff01;&#xff01; 重新安装&#xff1a;npm config set registry https://registry.npmmirror.c…

推荐?还是踩雷?3款中英互译软件大盘点,你真的选对了吗?

作为一个爱到处跑的人&#xff0c;我特别明白旅行的时候能说会道有多重要。不管是跟当地人聊天&#xff0c;还是看路标、菜单&#xff0c;有个好用的翻译软件是肯定少不了的。今天&#xff0c;我打算给你们介绍3款中英文互译的翻译工具&#xff0c;帮你挑出最适合自己的那一个。…

机器学习:opencv--人脸检测以及微笑检测

目录 前言 一、人脸检测的原理 1.特征提取 2.分类器 二、代码实现 1.图片预处理 2.加载分类器 3.进行人脸识别 4.标注人脸及显示 三、微笑检测 前言 人脸检测是计算机视觉中的一个重要任务&#xff0c;旨在自动识别图像或视频中的人脸。它可以用于多种应用&#xff0…

Python和MATLAB锂电铅蓄电化学微分模型和等效电路

&#x1f3af;要点 对比三种电化学颗粒模型&#xff1a;电化学的锂离子电池模型、单粒子模型和带电解质的单粒子模型。求解粒子域内边界通量与局部电流密度有关的扩散方程。扩展为两个相的负或正电极复合电极粒子模型。模拟四种耦合机制下活性物质损失情况。模拟锂离子电池三参…

【PhpSpreadsheet】ThinkPHP5+PhpSpreadsheet实现批量导出数据

目录 前言 一、安装 二、API使用 三、完整实例 四、效果图 前言 为什么使用PhpSpreadsheet&#xff1f; 由于PHPExcel不再维护&#xff0c;所以建议使用PhpSpreadsheet来导出exlcel&#xff0c;但是PhpSpreadsheet由于是个新的类库&#xff0c;所以只支持PHP7.1及以上的版…

服务器数据恢复—RAID5阵列上层Linux操作系统中节点损坏的数据恢复案例

服务器数据恢复环境&#xff1a; 一台服务器上有一组由5块硬盘&#xff08;4块数据盘1块热备盘&#xff09;组建的raid5阵列。服务器安装Linux Redhat操作系统&#xff0c;运行一套基于oracle数据库的OA系统。 服务器故障&#xff1a; 这组raid5阵列中一块磁盘离线&#xff0c…

观测云 AI 助手上线:智能运维,从此触手可及!

在当前的云原生时代&#xff0c;运维的复杂性和数据的爆炸式增长给企业带来了前所未有的挑战。为了帮助企业高效应对这些挑战&#xff0c;观测云自豪地推出了 AI 助手——智能化的运维助手&#xff0c;让每位用户都能轻松驾驭复杂的可观测性场景。 01 你身边的 PE 助手&#x…

《重置MobaXterm密码并连接Linux虚拟机的完整操作指南》

目录 引言 一、双击MobaXterm_Personal_24.2进入&#xff0c;但是忘记密码。 那么接下来请跟着我操作。 二、点击此链接&#xff0c;重设密码。 三、下载完成后&#xff0c;现在把这个exe文件解压。注意解压要与MobaXterm_Personal_24.2.exe在同一目录下哦&#xff0c;不然…

vim编辑器交换文件的产生与处理方法

文章目录 问题附图交换文件的作用和产生原因报错信息解读解决方法恢复文件使用命令行删除在文件管理器中删除在文本编辑器中处理 问题附图 简要分析 这个报错信息是由 vim 编辑器产生的&#xff0c;它表明在你尝试打开文件 /opt/software/openGauss/clusterconfig.xml 时&#…

MyBatis实践:提高持久层数据处理效率

文章目录 1 Mybatis简介1.1 简介1.2 持久层框架对比 2 快速入门2.1 准备数据库2.2 项目搭建2.3 依赖导入2.4 准备MyBatis配置文件2.5 实体类准备2.6 准备Mapper接口和MapperXML文件2.7 运行和测试 3. 核心配置文件4. MyBatis进阶使用4.0 以包为单位&#xff0c;引入所有的映射文…

一次性入门三款分布式定时任务调度框架:Quartz、ElasticJob3.0、xxl-job

分布式定时任务调度框架&#xff08;文末有源码&#xff09; 前言1、Quartz1.1 数据库1.2 maven依赖1.3 代码实现1.3.1 创建一个job1.3.1 为job设置trigger 1.4 配置文件1.5 启动、测试1.1 单机1.2 集群 2、ElasticJob2.1 下载zk2.2 新建三个类型的作业2.3 配置文件2.4 启动项目…

Nature?拿捏~

之前有分享过很多《Nature》论文插图&#xff0c;想着为大家提供更加广阔的作图思路。 但有人说&#xff0c;这些图好看是好看&#xff0c;可惜也就大佬们能画&#xff0c;跟我这个小卡拉米没啥关系。 此言差矣。 如果我说&#xff0c;Matlab就能画呢&#xff1f; 比如&…

AIGC助力小学生编程梦:C++入门不再难!

文章目录 一、AIGC时代下的编程教育新趋势二、小学生C入门趣味编程的意义三、小学生C入门趣味编程的实践策略四、面临的挑战与应对策略五、AIGC技术在小学生C编程中的应用与前景《小学生C趣味编程从入门到精通》编辑推荐内容简介作者简介目录 随着人工智能生成内容&#xff08;…

C++初阶——入门

目录 1、C发展历史 2、C版本更新 3、C参考文档 4、C书籍推荐 5、C的程序 6、命名空间 6.1 namespace的作用 6.2 namespace的定义 6.3 namespace的使用 7、C输入&输出 8、缺省参数 9、函数重载 10、引用 10.1 引用的概念和定义 10.2 引用的特性 10.3 引用的使…

10月9日

肯定是对x求导 刨根问底求导数解析式 区间再现均值不等式 没利用B-E 0 同解方程组 趋于0的时候&#xff0c;看1次项 没有考虑x -1的情况 还要加一&#xff0c;非齐次解

AdaTAD(CVPR 2024)视频动作检测方法详解

前言 论文&#xff1a;End-to-End Temporal Action Detection with 1B Parameters Across 1000 Frames 代码&#xff1a;AdaTAD 从论文标题可以看出&#xff0c;AdaTAD 可以在 1B 参数且输入视频在 1000 帧的情况下实现端到端的训练&#xff0c;核心创新点是引入 Temporal-Inf…

STM32_实验4_控制蜂鸣器

1.设置 PB2 引脚&#xff0c;生成代码。 2.打开蜂鸣器 // 循环反复HAL_GPIO_WritePin(GPIOB, GPIO_PIN_2, GPIO_PIN_SET); // 开启蜂鸣器printf("beep on\n");HAL_Delay(500); // 等待响500msHAL_GPIO_WritePin(…

解锁C++多态的魔力:灵活与高效的编码艺术(下)

文章目录 前言&#x1f3b1;四、多态的原理&#x1f52e;4.1 虚函数表&#xff08;vtable&#xff09;&#x1f52e;4.2 派生类对象中的虚函数表4.2.1 编写程序去访问虚函数表4.2.2 虚表存储位置的验证 &#x1f3b1;五、 多态的静态绑定和动态绑定&#x1f52e;5.1 静态绑定&a…

spring底层原理

本文参考黑马程序员的spring底层讲解&#xff0c;想要更详细的可以去看视频。 另外文章会每日更新&#xff0c;大概持续1个月&#xff01;&#xff01;&#xff01;每天更新一讲 这部分比较抽象&#xff0c;要经常复习&#xff01;&#xff01;&#xff01; 一、BeanFactory与A…