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

【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~

相关文章:

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

文章目录 一、什么是文件1.程序文件2.数据文件 二、数据文件1.文件名2.数据文件的分类文本文件二进制文件 三、文件的打开和关闭1.流和标准流流标准流 2.文件指针3.文件的打开和关闭文件的打开文件的关闭 四、文件的顺序读写1.fgetc函数2.fputc函数3.fgets函数4.fputs函数5.fsc…...

今日总结10.18

Exception 和Error 有什么区别 Exception和Error都是Java等编程语言中异常处理机制的重要组成部分&#xff0c;它们都继承自Throwable类。以下是两者的主要区别&#xff1a; 定义与性质 Error&#xff1a; 1.表示严重的系统级错误&#xff0c;如内存溢出&#xff08;OutOfM…...

React Agent 自定义实现

目录 背景 langchin 中的 agent langchin 中 agent 的问题 langchain 的 agent 案例 自定义 React Agent 大模型 工具定义 问题设定 问题改写&#xff0c;挖掘潜在意图 React Prompt 下一步规划 问题总结 代码 背景 之前使用过 langchian 中的 agent 去实现过一些…...

RabbitMQ 入门(六)SpringAMQP五种消息类型(Direct Exchange)

一、发布订阅-DirectExchange&#xff08;路由模式&#xff09; 在Fanout模式中&#xff0c;一条消息&#xff0c;会被所有订阅的队列都消费。但是&#xff0c;在某些场景下&#xff0c;我们希望不同的消息被不同的队列消费。这时就要用到Direct类型的Exchange。 Direct Exchan…...

2062:【例1.3】电影票

【题目描述】 已知一位小朋友的电影票价是10元&#xff0c;计算x位小朋友的总票价是多少&#xff1f; 【输入】 输入x。 【输出】 人数和电影票总价&#xff0c;中间用一个空格隔开。 【输入样例】 2 【输出样例】 2 20 Code #include<iostream> using namespace st…...

Python | Leetcode Python题解之第477题汉明距离总和

题目&#xff1a; 题解&#xff1a; class Solution:def totalHammingDistance(self, nums: List[int]) -> int:n len(nums)ans 0for i in range(30):c sum(((val >> i) & 1) for val in nums)ans c * (n - c)return ans...

Leecode刷题之路第25天之K个一组翻转链表

题目出处 25-K个一组翻转链表-题目出处 题目描述 给你链表的头节点 head &#xff0c;每 k 个节点一组进行翻转&#xff0c;请你返回修改后的链表。k 是一个正整数&#xff0c;它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍&#xff0c;那么请将最后剩余的节点保…...

nuxtjs3 使用tailwindcss做自适应

步骤 1: 安装 Tailwind CSS npm install tailwindcss postcss autoprefixer nuxtjs/tailwindcss步骤 2: 配置 Tailwind CSS 这将生成一个 tailwind.config.js 文件。 npx tailwindcss init步骤 3: 配置 nuxt.config.ts // https://nuxt.com/docs/api/configuration/nuxt-con…...

数据资产目录构建方法与应用

一、引言随着大数据、云计算、人工智能等技术的飞速发展&#xff0c;数据驱动已经成为企业发展的新引擎。数据资产目录作为数据管理的核心工具&#xff0c;不仅能够帮助企业更好地掌握自身数据资源的状况&#xff0c;还能为数据资产的全生命周期管理提供有力支撑。因此&#xf…...

【Python爬虫实战】从文件到数据库:全面掌握Python爬虫数据存储技巧

&#x1f308;个人主页&#xff1a;https://blog.csdn.net/2401_86688088?typeblog &#x1f525; 系列专栏&#xff1a;https://blog.csdn.net/2401_86688088/category_12797772.html 目录 前言 一、文本文件数据存储的基础 二、如何将爬取的数据存储为.txt文件 三、如何…...

断其一指,无惧!ProFusion3D: 相机或者激光失效仍高效的多传感器融合3D目标检测算法

Abstract 多传感器融合在自动驾驶中的3D目标检测中至关重要&#xff0c;摄像头和激光雷达是最常用的传感器。然而&#xff0c;现有方法通常通过将两种模态的特征投影到鸟瞰视角&#xff08;BEV&#xff09;或透视视角&#xff08;PV&#xff09;来进行单视角的传感器融合&…...

CCS字体、字号更改+CCS下载官方链接

Step1、 按照图示箭头操作 step2 Step3 点击确定&#xff0c;点击Apply(应用)&#xff0c;点击Apply and close(应用和关闭) 4、历代版本下载链接 CCS下载&#xff1a;官方链接https://www.ti.com/tool/CCSTUDIO The last but not least 如果成功的解决了你的问题&#x…...

YOLO11改进|注意力机制篇|引入SEAM注意力机制

目录 一、【SEAM】注意力机制1.1【SEAM】注意力介绍1.2【SEAM】核心代码二、添加【SEAM】注意力机制2.1STEP12.2STEP22.3STEP32.4STEP4三、yaml文件与运行3.1yaml文件3.2运行成功截图一、【SEAM】注意力机制 1.1【SEAM】注意力介绍 下图是【SEAM】的结构图,让我们简单分析一下…...

简历修订与求职经历 - Chap04

节后第一周有点山中无甲子的状况。Oct08&#xff0c;节后第一天几乎全天处于心流状态。上午下午很快时间就结束了。 周五&#xff0c;按照既有的面试频次&#xff0c;感觉可以做点别的。然后就联系了附近的驾校&#xff0c;打算把摩托车驾驶证拿了。然后几乎到了驾校&#xff…...

鸿蒙开发案例:推箱子

推箱子游戏&#xff08;Sokoban&#xff09;的实现。游戏由多个单元格组成&#xff0c;每个单元格可以是透明的、墙或可移动的区域。游戏使用Cell类定义单元格的状态&#xff0c;如类型&#xff08;透明、墙、可移动区域&#xff09;、圆角大小及坐标偏移。而MyPosition类则用于…...

mysql--表的约束

目录 理解表的约束和操作 如何理解&#xff1f; 1、空属性null 2、默认值default 3、列描述comment 4、自动填充zorefill 5、主键primary key &#xff08;1&#xff09;创建表时指定可以 &#xff08;2&#xff09;创建表后指定key &#xff08;3&#xff09;删除主…...

Ubuntu 上安装 docker 并配置 Docker Compose 详细步骤

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storm…...

MySQL去除空白字符(如非标准空格、制表符等)

在 MySQL 中&#xff0c;需要去除 site_name 字段的空格&#xff0c;可以使用 TRIM() 函数。这个函数可以去掉字符串开头和结尾的空格。以下是一个示例查询&#xff0c;演示如何选择去除空格后的 site_name&#xff1a; SELECT TRIM(site_name) AS site_name FROM site_info;如…...

2063:【例1.4】牛吃牧草

【题目描述】 有一个牧场&#xff0c;牧场上的牧草每天都在匀速生长&#xff0c;这片牧场可供15头牛吃20天&#xff0c;或可供20头牛吃10天&#xff0c;那么&#xff0c;这片牧场每天新生的草量可供几头牛吃1天&#xff1f; 【输入】 &#xff08;无&#xff09; 【输出】 如题…...

QT开发:深入掌握 QtGui 和 QtWidgets 布局管理:QVBoxLayout、QHBoxLayout 和 QGridLayout 的高级应用

目录 引言 1. QVBoxLayout&#xff1a;垂直布局管理器 基本功能 创建 QVBoxLayout 添加控件 添加控件和设置对齐方式 设置对齐方式 示例代码与详解 2. QHBoxLayout&#xff1a;水平布局管理器 基本功能 创建 QHBoxLayout 添加控件 添加控件和设置对齐方式 设置对齐…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

【Java学习笔记】Arrays类

Arrays 类 1. 导入包&#xff1a;import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序&#xff08;自然排序和定制排序&#xff09;Arrays.binarySearch()通过二分搜索法进行查找&#xff08;前提&#xff1a;数组是…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

dify打造数据可视化图表

一、概述 在日常工作和学习中&#xff0c;我们经常需要和数据打交道。无论是分析报告、项目展示&#xff0c;还是简单的数据洞察&#xff0c;一个清晰直观的图表&#xff0c;往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server&#xff0c;由蚂蚁集团 AntV 团队…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》

这段 Python 代码是一个完整的 知识库数据库操作模块&#xff0c;用于对本地知识库系统中的知识库进行增删改查&#xff08;CRUD&#xff09;操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 &#x1f4d8; 一、整体功能概述 该模块…...

在 Spring Boot 中使用 JSP

jsp&#xff1f; 好多年没用了。重新整一下 还费了点时间&#xff0c;记录一下。 项目结构&#xff1a; pom: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://ww…...