C语言进阶---文件操作

news2024/11/15 11:05:27

1、什么是文件

磁盘上的文件是文件

但是在程序设计中,我们一般谈的文件有两种:程序文件、数据文件。(从文件功能的角度来分类的)。

1.1、程序文件

包括源程序文件(后缀为.c),目标文件(windows环境后缀为.ob),可执行文件(windows环境后缀为.exe)。

1.2、数据文件

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

本章讨论的是数据文件。

1.3、文件名

一个文件要有一个唯一的文件标识,以便用户识别和引用。

文件包含3部分:文件路径+文件名主干+文件后缀。

例如:c:\code\test\aa.txt

为了方便起见,文件标识常被称为文件名

2、文件的打开和关闭

2.1、文件指针

缓冲文件系统中,关键的概念是__文件类型指针__,简称"文件指针"。

每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)。这些信息是保存在一个结构体变量中的。该结构体类型是由系统声明的,取名__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;

每当打开一个文件的时候,系统会根据文件的情况自动创建一个FILE结构的变量,并填充其中的信息,使用者不必关心细节。

一般都是通过一个FILE的指针来维护这个FILE结构的变量,这样使用起来更加方便。

打开文件的大致流程就是,如下:

有一个test.txt文件,在使用fopen打开时,会在内存中有一个FILE类型的文件信息区,如何维护这个文件信息区呢?通过一个FILE*的指针,来指向这个文件信息区。而指针指向文件信息区,而文件信息区和文件有关联,因此FILE*指针和文件就有了联系。

在这里插入图片描述

C语言中打开文件使用fopen函数,当fopen打开文件的时候,会在内存中创建文件信息区,并且把文件信息区的起始地址返回来。因为文件信息区是FILE类型的,那既然返回的是文件信息区的地址,所以文件信息区的地址就是FILE*类型的,FILE*就是文件指针。

下面来创建一个FILE*的指针变量:

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

定义pf是一个指向FILE类型数据的指针变量,可以使pf指向某个文件的文件信息区(是一个结构体变量)。通过该文件信息区中的信息就能够访问该文件。也就是说,通过文件指针变量能够找到与它关联的文件。

在这里插入图片描述

2.2、文件的打开和关闭

文件在读写之前应该先打开文件,在使用结束之后应该关闭文件。

在编写程序的时候,在打开文件的同时,都会返回一个FILE*的指针变量指向该文件,也相当于建立了指针和文件的关系。

ANSIC规定使用fopen函数打开文件,fclose来关闭文件。

//打开文件          
//mode使文件的打开模式,
//"r"---------只读
//"w"---------只写        a、r+、w+、a+
FILE* fopen(const char* filename,const char* mode);

//关闭文件
int fclose(FILE* stream);
#include <stdio.h>
#

int main()
{
	FILE* pf = fopen("test.txt", "r");
	return 0;
}

但是有可能文件打开失败,比如:此文件不存在。如果文件打开失败,会返回空指针。所以我们需要判断一下:

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <errno.h>

int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		printf("%s\n", strerror(errno));
		return 1;
	}
	return 0;
}

关闭文件:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <errno.h>

int main()
{ 
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		printf("%s\n", strerror(errno));
		return 1;
	}
	fclose(pf);
	pf = NULL;
	return 0;
}

2.3、文件打开方式

文件使用方式含义如果指定文件不存在
“r”(只读)为了输入数据,打开一个已经存在的文本文件出错
“w”(只写)为了输出数据,打开一个文本文件新建一个文件
“a”(追加)向文本文件末尾添加数据新建一个文件
“rb”(只读)为了输入数据,打开一个二进制文件出错
“wb”(只写)为了输出数据,打开一个二进制文件新建一个文件
“ab”(追加)向一个二进制文件末尾添加数据出错
“r+”(读写)为了读和写,打开一个已经存在的文本文件出错
“w+”(读写)为了读和写,新建一个文件新建一个文件
“a+”(读写)打开一个文件,在文件末尾进行读写新建一个文件

3、关于文件输出和输入

在这里插入图片描述

  • 写和输出是同一概念,所对应的操作是:内存中的数据到硬盘(或外部设备)中的文件里面区。
  • 读和输入时同一概念,所对应的操作是:硬盘(或外部设备)中文件的数据到内存中去。

文件流如何理解呢?

外部设备其实有很多:硬盘,屏幕,U盘…

每一种外部设备读和写的方式是不一样的。那我们作为程序员,我们在对文件操作时,我们面对不同的外部设备就需要考虑不同的读写的方式,那这对于程序员来说太麻烦了。为了很好的解决此问题,使得程序员不需要太多关注外部设备的读和写。我们在外部设备前面封装了一层。这一层就是。我们先把数据写入里面去,这对于程序员来说就够了,而至于又是将数据如何写进各种外部设备中去的,这个我们不需要关心,流里面的数据是如何到外部设备中去的,是C语言底层设计好,帮我们自动实现的。

那我们在使用printfscanf时怎么不需要先打开一个流呢?

这是因为C语言在运行时默认打开了三个流:

  • FILE* stdin ------ 标准输入流(键盘)。
  • FILE* stdout ------ 标准输出流(屏幕)。
  • FILE* stderr ------ 标准错误流(屏幕)。

所以说我们在使用printfscanf时不需要先创建一个FILE*,而是直接使用即可。

4、文件的顺序读写

功能函数名适用于
字符输入函数fgetc所有输入流
字符输出函数fputc所有输出流
文本行输入函数fgets所有输入流
文本行输出函数fputs所有输出流
格式化输入函数fscanf所有输入流
格式化输出函数fprintf所有输出流
二进制输入fread文件
二进制输出fwrite文件

输入:从文件中读信息到内存中去。

输出:把一个信息写入文件中去。

4.1、fputc—写字符(针对字符)

int fputc ( int character, FILE * stream );

//eg:
fputc('a', pf);         //传参字符,以ASCII值存入

代码演示:

//fputc

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <errno.h>

int main()
{ 
	//打开文件
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		printf("%s\n", strerror(errno));
		return 1;
	}
	//写文件
    //在上面的test.txt文件中写入一个字符'a'。
	fputc('a', pf);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

4.2、fgetc—读字符(针对字符)

int fgetc ( FILE * stream );

//eg:
fgetc(pf);
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <errno.h>

int main()
{ 
	//打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		printf("%s\n", strerror(errno));
		return 1;
	}
	//写字符
	fputc('a', pf);
	//读字符
	int ch = 0;
	ch = fgetc(pf);
	printf("%c ", ch);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

【补充:】fgets读取字符,如果读取失败会返回EOF。

4.3、fputs—写一行数据(针对字符串)

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

//eg:
fputs("hello bbb", pf);

代码演示:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <errno.h>

int main()
{ 
	//打开文件
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{ 
		printf("%s\n", strerror(errno));
		return 1;
	}
	//写一行数据
	fputs("hello bbb", pf);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

4.4、fgets—读一行数据(针对字符串)

char * fgets ( char * str, int num, FILE * stream );
  • str:读取的字符串,要存放在那个地址
  • num:读取多少个字符
  • stream:要操作的文件

代码示例:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <errno.h>

int main()
{ 
	//打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{ 
		printf("%s\n", strerror(errno));
		return 1;
	}
	//读取数据
	char arr[20];
	fgets(arr, 5, pf);
	printf("%s\n", arr);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

输出:

在这里插入图片描述

我们从"hello bbb"里面只读取了前4个字符,明明我们指定的5个字符。这是因为fgets会自动在第5个字符位置上添加’\0’,所以只读取到前4个字符。

4.5、fprintf—写 格式化数据

上面的函数,读或者写都是指针字符的。

而如果想要写或者读其它的数据呢?比如说:结构体数据。

可以使用fprintf或者fscanf。而写数据需要用fprintf

学习这个函数可以和printf进行对比。

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

下面来看一下prinft的使用:

int printf ( const char * format, ... );

可以发现,fprintf比printf就多个参数:FILE* stream,那我无非就是多个要操作的文件。

一般情况下,printf会这样写:

printf("%s %d %f",a,b,c);

那类比printf,我们就可以写出fprintf的使用,下面来写入结构体数据为例:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <errno.h>

struct S
{
	char arr[20];
	int age;
	float b;
};

int main()
{ 
	struct S s = { "aaa",12,3.1f };
	//打开文件
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{ 
		perror("eg");
		return 1;
	}

	fprintf(pf, "%s %d %f", s.arr, s.age, s.b);

	fclose(pf);
	pf = NULL;
	return 0;
}

4.6、fscanf—读 格式化数据

函数使用:

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

学这个函数可以和scanf进行对比:

int scanf ( const char * format, ... );

可以发现,fscanf就是比scanf多个文件流的参数。

我们先来看看scanf的使用方法:

scanf("%s %d %f",&a,&b,&c);

那再来看看fscanf的使用:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <errno.h>

struct S
{
	char arr[20];
	int age;
	float b;
};

int main()
{ 
	struct S s = {0};
	//打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{ 
		perror("eg");
		return 1;
	}

	fscanf(pf,"%s %d %f", s.arr, &(s.age), &(s.b));
	printf("%s %d %f", s.arr, s.age, s.b);

	fclose(pf);
	pf = NULL;
	return 0;
}

输出:

在这里插入图片描述

4.7、【补充:】使用以上函数打印数据到屏幕或从屏幕输入数据

fprintf(stdout,"%s %d %f", s.arr, s.age, s.b);


//很简单,只需要在前面添加"stdout"标准输出流即可。

4.8、fwrite—二进制输出

参数说明:

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

  • ptr:需要写入的数据来自于哪里。
  • size:一个元素有多大。
  • count:一共多少个元素。
  • stream:文件流。

代码演示:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <errno.h>

struct S
{
	char arr[20];
	int age;
	float b;
};

int main()
{ 
	struct S s = {"zhangsan",18,30.1f};
	//以二进制的形式写入文件中。
	FILE* pf = fopen("test.txt", "wb");
	if (pf == NULL)
	{ 
		perror("fopen");
		return 1;
	}

	//以二进制的方式写
	fwrite(&s, sizeof(struct S), 1, pf);

	fclose(pf);
	pf = NULL;
	return 0;
}

4.9、fread—二进制输入

参数说明:

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

参数使用和fwrite一样。

代码演示:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <errno.h>

struct S
{
	char arr[20];
	int age;
	float b;
};

int main()
{ 
	struct S s = {"zhangsan",18,30.1f};
	//以二进制的形式写入文件中。
	FILE* pf = fopen("test.txt", "rb");
	if (pf == NULL)
	{ 
		perror("fopen");
		return 1;
	}

	//以二进制的方式读
	fread(&s, sizeof(struct S), 1, pf);
	printf("%s %d %f\n", s.arr, s.age, s.b);

	fclose(pf);
	pf = NULL;
	return 0;
}

5、对比一组函数,并使用sprintf和sscanf

scanf/fscanf/sscanf

printf/fprintf/sprintf

  • scanf是针对标准输入的格式化输入语句。

  • printf是针对标准输出的格式化输出语句。

  • fscanf是针对所有输入流的格式化输入语句。

  • fprintf是针对所有输出流的格式化输出语句。

下面介绍sprintfsscanf这两个函数和上面的函数的最大区别就是,不在对文件进行操作了。和文件流没有什么关系了。

5.1、sprintf—把一个格式化的数据写到字符串中。

参数说明:

int sprintf ( char * str, const char * format, ... );

sprintf的作用:把一个格式化的数据写到字符串中,本质是把一个格式化的数据转为一个字符串。

这个函数和上面的函数最大的区别就是,它不再是对文件进行操作了,和FILE*没有什么关系了。

代码演示:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <errno.h>

struct S
{
	char arr[20];
	int age;
	float b;
};

int main()
{ 
	struct S s = {"zhangsan",18,30.1f};
	//将结构体数据(格式化数据)转为字符串
	char buf[100];
	sprintf(buf, "%s %d %f\n", s.arr, s.age, s.b);
	printf("%s\n", buf);
	return 0;
}

输出:

在这里插入图片描述

现在的数据是以字符串的形式:"zhangsan 18 30.100000"存储了。

5.2、sscanf—从一个字符串中转化为一个格式化数据

参数说明:

int sscanf ( const char * s, const char * format, ...);

代码演示:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <errno.h>

struct S
{
	char arr[20];
	int age;
	float b;
};

int main()
{ 
	struct S s = {"zhangsan",18,30.1f};
	struct S tmp = { 0 };
	//将结构体数据(格式化数据)转为字符串
	char buf[100];
	sprintf(buf, "%s %d %f\n", s.arr, s.age, s.b);
    //将结构体数据以字符串的形式打印
	printf("%s\n", buf);

	//现在buf里面存储的是字符串
	//现在使用sscanf从字符串buf中获取一个格式化数据到tmp结构体中。
	sscanf(buf, "%s %d %f", tmp.arr, &(tmp.age), &(tmp.b));
    //将字符串数据以结构体形式打印。
	printf("%s %d %f\n", tmp.arr,tmp.age,tmp.b);
	return 0;
}

输出:

在这里插入图片描述

6、文件的随机读写

6.1、fseek—根据文件指针的位置和偏移量来定位文件指针。

根据文件指针的位置和偏移量来定位文件指针。

int fseek(FILE* stream,long int offset,int origin);

  • stream:文件流

  • offset:偏移量

  • origin:这个有三个取值:

    • SEEK_SET文件起始位置
      SEEK_CUR当前指针位置
      SEEK_END文件结尾

在上面介绍了一个函数:fgetc,可以输入文件中的字符。

比如现在有字符串:“abcdef”。第一次执行fgetc就会读取字符’a’,第二次执行fgetc就会读取字符’b’,第三次执行fgetc就会读取字符’c’…

就是只能一个字符一个字符的读取。

那现在有需求:我们直接读取字符’c’,然后在读取字符’e’,就是我们读取谁就读取谁呢?

答案:可以。使用fseek。

代码演示:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return;
	}
	//定位文件指针
	fseek(pf, 2, SEEK_SET);
	//会直接读取字符'c'
	int ch = fgetc(pf);
	printf("%c\n", ch);

	//SEEK_CUR代表当前的文件指针位置,因为上面文件指针指向了字符c的位置,所以现在从字符c位置开始。
	fseek(pf, 2, SEEK_CUR);   
	ch = fgetc(pf);     //从c开始,偏移量是2,所以会读取到字符f。
	printf("%c\n", ch);

	fclose(pf);
	pf = NULL;
	return 0;
}

6.2、ftell—计算前文件指针相对于起始位置的偏移量。

返回文件指针相对于起始位置的偏移量

long int ftell(FILE* stream);

计算当前文件指针相对于起始位置的偏移量。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return;
	}
	//定位文件指针
	fseek(pf, 2, SEEK_SET);
	//会直接读取字符'c'
	int ch = fgetc(pf);
	//打印偏移量,由于fgetc把字符c读取了,所以现在文件指针指向了d,因此偏移量应该为3
	printf("%d\n", ftell(pf));
	
	fseek(pf, 2, SEEK_CUR);   
	ch = fgetc(pf);     
	//打印偏移量,由于fgetc把字符f读取了,所以现在文件指针指向了f后面,因此偏移量应该为6
	printf("%d\n", ftell(pf));

	fclose(pf);
	pf = NULL;
	return 0;
}

输出:

在这里插入图片描述

6.3、rewind

让文件指针的位置返回到文件的其实位置。

void rewind(FILE* stream);

例子:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return;
	}
	//定位文件指针
	fseek(pf, 2, SEEK_SET);
	//会直接读取字符'c'
	int ch = fgetc(pf);
	//由于文件指针回到了起始位置,所以下面的偏移量为0。
	rewind(pf);
	printf("%d\n", ftell(pf));
	
	
	fclose(pf);
	pf = NULL;
	return 0;
}

输出:

在这里插入图片描述

7、文本文件和二进制文件

根据数据的组织形式,数据文件被称为文本文件或者二进制文件。

数据在内存中以二进制的形式存储,如果不加转换的输出到外序,就是二进制文件。

如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的文件就是文本文件。

一个数据在内存中是怎样存储的呢?

字符一律以ASCII形式存储,数值行数据既可以用ASCII形式存储,也可以使用二进制形式存储。如果有整数10000,如果以ASCII码的形式输出到磁盘,则磁盘占用5个字节(每个字符一个字节)而二进制形式输出,则在磁盘上只占4个字节(VS2013测试)。

8、文件读取结束的判定

8.1、被错误使用的feof

牢记:在文件读取过程中,不能用feof函数的返回值直接用来判断文件是否结束。

而是__应用于当文件读取结束的时候,判断是读取失败结束,还是遇到文件尾结束__。

  • feof(pf)为真,说明是读到文件尾结束,为假说明是读取失败(读取错误)。
  • ferror(pf)为真,说明是读取失败(读取错误),并没有成功的读取到文件尾。

1、文本文件读取是否结束,判断返回值是否为EOF(fgetc),或者NULL(fgets),例如

  • fgetc判断是否为EOF
  • fgets判断返回值是否尾NULL。

2、二进制文件的读取结束判断,判断返回值是否小于实际要读的个数。

例如:

  • fread判断返回值是否小于实际要读个数。

9、文件缓冲区

ANSIC标准采用"缓冲文件系统"处理数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每一个正在使用的文件开辟一块’ 文件缓冲区"。从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才-起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区) , 然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根据C编译系统决定的。

在这里插入图片描述

代码示例:

//环境VS2022,Win10

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>

int main()
{
	FILE* pf = fopen("test.txt", "w");
	fputs("abcdef", pf);         //先将代码放在输出缓冲区
	printf("睡眠10秒--已经写好数据,打开test.txt文件,发现文件没有内容\n");
	Sleep(10000);
	printf("刷新输出缓冲区\n");
	fflush(pf);//刷新缓冲区时,才将输出缓冲区的数据写到文件(磁盘)。
	printf("在睡眠10秒--已经写好数据,打开test.txt文件,发现文件有内容\n");
	Sleep(10000);
	fclose(pf);//注:fclose在关闭文件的时候,也会刷新缓冲区。
	return 0;
}

这里可以得出一个结论:

因为有缓冲区的存在,C语言在操作文件的时候,需要做刷新缓冲区或者在文件操作结束的时候关闭文件。

如果不做,可能导致读写文件的问题。

10、数据,缓冲区,流,外部设备

在这里插入图片描述

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

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

相关文章

若依(ruoyi-cloud)脚手架解读,一篇精通,包票上手~

视频教程传送门&#xff1a; 基于SpringCloud Alibaba技术栈&#xff0c;若依微服务版(RuoYi-Cloud)脚手架入门精解&#xff0c;保证上手那种~_哔哩哔哩_bilibili基于SpringCloud Alibaba技术栈&#xff0c;若依微服务版(RuoYi-Cloud)脚手架入门精解&#xff0c;保证上手那种~…

vscode 插件系统的运行机制!

做vscode二次开发有一段时间了&#xff0c;平时都是任务比较重&#xff0c;最近有时间做下总结&#xff0c;详细的讲解下vscode 插件系统的运行机制&#xff0c;vscode做为最受欢迎的编辑器&#xff0c;有着庞大的插件市场。其插件系统确实很复杂&#xff0c;文章很长&#xff…

构建交互式数据集展示:Gradio的Dataset模块详解

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

Visual C++中的引用的具体理解

我是荔园微风&#xff0c;作为一名在IT界整整25年的老兵&#xff0c;今天来聊聊 Visual C中的引用。 在C中有一个引用的概念。引用就是一个变量的别名&#xff0c;它需要用另一个变量或对象来初始化自身。引用就像一个人的外号一样,例如:有一个人的名字叫诸葛大力&#xff0c;…

【压缩空气储能】非补燃压缩空气储能系统集成的零碳排放综合能源优化调度(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

软件工程作业创建表

设计表 4.按专业统计课程数量: sql SELECT Major, COUNT(*) AS Num FROM Course GROUP BY Major 5.按专业查询所有课程信息: sql SELECT * FROM Course WHERE Major 信息技术 6.统计“信息技术”专业的课程数量: sql SELECT COUNT(*) FROM Course WHERE Major 信息技术…

SIM长序列处理

原论文&#xff1a;Search-based User Interest Modeling with Lifelong Sequential Behavior Data for Click-Through Rate Prediction 主要是为了解决长序列带来的计算复杂度问题 解决方法是第一阶段先进性search&#xff0c;有softsearchhardsearch两种方式。 然后用mult-h…

SAP HANA使用SQL创建SCHEMA:

语法是 CREATE SCHEMA “<Schema_Name>” 使用图形方法创建 SAP HANA 表&#xff1a; 创建图形计算视图&#xff1a;

Spring面试题--单例bean是线程安全的吗?

Spring框架中的单例bean是线程安全的吗&#xff1f; 这个问题有一个前提 Spring框架中的bean是单例的吗&#xff1f; 答&#xff1a;是&#xff0c;我们可以通过scope注解来设置当前的bean是不是单例的 singleton : bean在每个Spring IOC容器中只有一个实例。 prototype&am…

LeetCode刷题 | 1143. 最长公共子序列、1035. 不相交的线、53. 最大子数组和

1143. 最长公共子序列 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 &#xff0c;返回 0 。 一个字符串的 子序列 是指这样一个新的字符串&#xff1a;它是由原字符串在不改变字符的相对顺序的情况下删除某些…

基于Python所写的今天吃什么小程序

点击以下链接获取源码资源&#xff1a; https://download.csdn.net/download/qq_64505944/87979945 《今天吃什么》程序使用说明 小程序端 启动WhatToEat/WhatToEat下的venv虚拟环境&#xff0c;运行python manage.py runserver命令启动Flask。然后打开微信开发者工具并扫码登…

MongoDB基础入门

目录 【认识MongoDB】 MongoDB的使用场景 MongoDB的结构模型 【安装MongoDB】 MacOS安装MongoDB Windows安装MongoDB 客户端连接 【认识MongoDB】 MongoDB是一个使用C语言编写的基于分布式文件存储的数据库&#xff0c;是一个开源的、高性能、高扩展、无模式的文档型…

Matlab SFM算法(两视图)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 基于运动恢复结构(SfM)是指从一组二维图像中估计场景中三维结构的过程。SfM算法被用于许多应用程序,例如3D扫描、增强现实和视觉同步定位和映射(vSLAM)。 SfM可以用许多不同的方法来计算。处理问题的方式取决于不同…

Quartz整合SpringBoot实现非持久化多任务运行

简介 java后端入门新手&#xff0c;对知识内容理解较浅&#xff0c;如文章内容有误&#xff0c;请各位大佬多多指点。本篇文章适用于对quartz有一定了解的入门新手&#xff0c;且并没有采用quartz官方的持久化方式&#xff0c;是在结合工作需求的基础上完成的quartz任务调度的…

【交换排序】手撕八大排序之快速排序和冒泡排序(超级详细)

目录 &#x1f341;一.快速排序 &#x1f340;Ⅰ.Hoare法 &#x1f347;Ⅱ.挖坑法 &#x1f34b;1.递归版本 &#x1f34a;2.关于时间复杂度 &#x1f34e;3.快速排序的优化之三数取中法 &#x1f34c;4.非递归版本&#xff08;使用栈实现&#xff09; &#x1f350;5…

什么是文件存储、对象存储、块存储?

什么是文件存储 文件存储带有文件系统&#xff0c;主要是以文件的形式存放数据&#xff0c;能将所有的目录、文件形成一个有层次的树形结构来管理&#xff0c;通过“树”不断伸展的枝丫就能找到你需要的文件。存储协议主要是NFS、CIFS等&#xff0c;以统一命名空间的形式共享一…

docker安装rabbitMQ,JAVA连接进行生产和消费,压测

1.docker安装 docker安装以及部署_docker bu shuminio_春风与麋鹿的博客-CSDN博客 2.doker安装rabbitMQ 使用此命令获取镜像列表 docker search rabbitMq 使用此命令拉取镜像 docker pull docker.io/rabbitmq:3.8-management 这里要注意&#xff0c;默认rabbitmq镜像是…

剑指 Offer 47: 礼物的最大价值

这道题看的出来只能往右往下只能走4步。 应该是每次i或者j加1&#xff01;不是先j后i 用for循&#xff0c;由于横纵坐标是固定的值&#xff08;一条直线&#xff09;&#xff0c;所以i0&#xff0c;j所有情况这种组合可以全部计算出来&#xff0c;当i1时&#xff0c;j0这里也…

图像的IO操作

1.读取图像 cv.imread()2.显示图像 cv.imshow()3.保存图像 cv.imwrite()4.参考代码 import numpy as np import cv2 as cv import matplotlib.pyplot as plt# 1.读取图像&#xff1a;默认方式是彩色图 img cv.imread("yangmi.jpg") # 彩色图 gray_img cv.imre…

C语言进阶---程序的编译(预处理操作)+链接

1、程序的翻译环境和执行环境 在ANSI C的任何一种实现中&#xff0c;存在两个不同的环境。 第1种是翻译环境&#xff0c;在这个环境中源代码被转换为可执行的机器指令。 第2种是执行环境&#xff0c;它用于实际执行代码。 1、每个源文件单独经过编译器处理&#xff0c;或生成一…