C语言之文件操作

news2025/1/18 7:17:43

个人主页:平行线也会相交
欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 平行线也会相交 原创
收录于专栏【C/C++】
在这里插入图片描述

目录

  • 文件的打开和关闭
    • 文件打开
      • "r"
      • "w"
        • 注意有一个小细节
  • 文件的顺序读写
    • 字符输入输出函数fgetc和fputc
      • fputc
      • fgetc
      • 补充
    • 文本行输入输出函数fgets和fputs
    • 格式化输入输出函数
      • fprintf
      • fscanf
      • 注意
      • 对比一组函数
    • 二进制输入和输出
      • fwrite
      • fread
  • 文件的随机读写
    • fseek
    • ftell
    • rewind
  • 文件结束的判定
    • 什么是EOF
    • feof
    • perror

文件的打开和关闭

文件再读写之前应该先打开文件,在使用结束之后应该关闭文件
在编写程序的时候,再打开文件的同时,都会返回一个FILE*的指针变量指向该文件,也相当于建立了指针和文件的关系。
ANSIC规定使用fopen函数来打开文件,使用fclose来关闭文件。

FILE * fopen(const char * filename, const char * mode);//mode是打开方式
int fclose (FILE * stream);

打开方式如下:

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

文件打开

#include<stdio.h>
int main()
{
	//打开文件test.txt
	//相对路径(即相对于当前的代码在哪个路径底下)
	//..表示上一级路径
	//. 表示当前路径
	//fopen("../test.txt","r");
	//fopen("../../test.txt","r");
	//fopen("test.txt","r");

	//绝对路径的写法
	//fopen("D:\\vs\code\\101\\C语言-文件操作\\C-文件操作(1)-22-12-1\\test.txt", "r");
	return 0;
}

“r”

#include<stdio.h>
#include<errno.h>
#include<string.h>
int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		{
			printf("%s", strerror(errno));
			return 0;
		}
	}
	//来到这里就说明打开成功了
	//读文件
	
	//关闭文件
	fclose(pf);//pf的类型就是FILE*
	//fclose就是把文件关闭掉,把FILE这个结构体所指向的文件关闭掉,把这个资源释放掉
	//但是此时pf并没有置成空指针,对于fclose(pf)属于值传递,并没有改变pf
	//所以我们就需要把pf置成空指针
	pf = NULL;
	return 0;
}

在这里插入图片描述
我们发现其实并没有成功打开文件,原因就是No such file or directory,即没有这个文件或者文件夹
我们在前面的表格中可以知道,"r"(只读)如果指定文件不存在的话会出错
所以我们需要创建test.txt文件之后再来运行程序:
在这里插入图片描述
此时我们来运行程序:
在这里插入图片描述
屏幕上什么都没有显示就说明打开文件成功了。

“w”

我们先把刚刚创建的test.txt文件删除掉。
因为如果以"w"(只写)的方式来打开文件时,如果指定文件不存在,会新建一个文件。
在这里插入图片描述

现在用只写的方式来打开文件:
在这里插入图片描述
说明程序打开成功了,我们再来看一看到底有没有创建test.txt文件。
在这里插入图片描述
这里的确创建了一个新的文件,在这个路径底下就自动生成test.txt文件。

注意有一个小细节

现在我们给test.txt文件中放入"abcdef",即:
在这里插入图片描述
在这里插入图片描述
现在我们来运行程序:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
当我们再次查看test.txt文件时发现文件是空的。
那为什么会出现这种情况呢?原因是:我们通过"w"(只写)来打开文件时,会新建一个文件出来,那么旧的那个、先前的那个文件里的内容就销毁掉了。即指定的文件存在与否都会新建一个文件

文件的顺序读写

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

字符输入输出函数fgetc和fputc

fputc

#include<stdio.h>
#include<string.h>
#include<errno.h>
int main()
{
	FILE* pfwrite = fopen("test.txt", "w");//pfwrite所指向的流是文件输出流,即我们要向文件里面写东西
	if (pfwrite == NULL)
	{
		printf("%s\n", strerror(errno));
	}
	//写文件
	fputc('h', pfwrite);
	fputc('e', pfwrite);
	fputc('l', pfwrite);
	fputc('l', pfwrite);
	fputc('o', pfwrite);
	//关闭文件
	fclose(pfwrite);
	pfwrite = NULL;
	return 0;
}

在这里插入图片描述

fgetc

//fgetc
#include<stdio.h>
#include<string.h>
#include<errno.h>
int main()
{
	FILE* pfread = fopen("test.txt", "r");//pfread所指向的流为输入流,叫文件输入流,即我们可以从文件中去读取信息
	if (pfread == NULL)
	{
		printf("%s\n", strerror(errno));
	}
	//读文件
	printf("%c", fgetc(pfread));
	printf("%c", fgetc(pfread));
	printf("%c", fgetc(pfread));
	printf("%c", fgetc(pfread));
	printf("%c", fgetc(pfread));
	//关闭文件
	fclose(pfread);
	pfread = NULL;
	return 0;
}

在这里插入图片描述
其实我们也可以这样写:

//fgetc
#include<stdio.h>
#include<string.h>
#include<errno.h>
int main()
{
	FILE* pfread = fopen("test.txt", "r");
	if (pfread == NULL)
	{
		printf("%s\n", strerror(errno));
	}
	//读文件
	int ch = fgetc(pfread);
	printf("%c", ch);
	ch = fgetc(pfread);
	printf("%c", ch);
	ch = fgetc(pfread);
	printf("%c", ch);
	ch = fgetc(pfread);
	printf("%c", ch);
	ch = fgetc(pfread);
	printf("%c", ch);
	//关闭文件
	fclose(pfread);
	pfread = NULL;
	return 0;
}

结果其实都一样的。
注意事项:以"r"(只读)的方式打开文件时必须确保文件已存在
在这里之所以可以把hello打印出来是因为已存在的test.txt文件中已经有hello

补充

我们平时从键盘输入,又或者输出到屏幕。其中键盘和屏幕都是外部设备,我们就可以做到从外部设备读取信息,也可以做到把信息写到外部设备上去。
值得注意的是,我们把我们下信息从键盘上读和我们把信息写到屏幕上时,不需要向文件一样需要打开和关闭文件;当我们把我们下信息从键盘上读和我们把信息写到屏幕上时从来没有说打开键盘或者关闭键盘,又或者打开屏幕、关闭屏幕。

键盘-标准输入设备-stdin
屏幕-标准输出设备-stdout
是一个程序默认打开的两个流设备
当程序执行起来时,会默认打开三个流,即键盘,屏幕,stderr。这三个流的类型都是FILE*
stdin(标准输入设备) FILE*
stdout(标准输出设备) FILE*
stderr FILE*

fgetcfputc均是适用于所有流的,既包括文件流,又包括标准输入流和标准输出流。
举例:

#include<stdio.h>
int main()
{
	int ch = fgetc(stdin);
	fputc(ch, stdout);
	return 0;
}

在这里插入图片描述
这个时候我们就发现fgetc可以从标准输入流里面去读取信息,fputc也可以写到标准输出流里面去。即从键盘上读然后输出到屏幕上去

文本行输入输出函数fgets和fputs

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

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

在这里插入图片描述

如果你观察仔细就是发现程序运行的结果多了一个空行。
倘若我把printf("%s\n", buf);中的\n去掉,变成printf("%s", buf);我们再来看一下运行结果:

在这里插入图片描述
这里需要我们注意的是这里printf在打印数组buf的时候,这里本身就拥有一个换行

现在我们来看这段代码:
在这之前我把test.txt文件中的内容换成了这个,即:
在这里插入图片描述

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

结果是这样的:
在这里插入图片描述
现在我们来看puts
在这里插入图片描述

在这里插入图片描述

//puts
#include<stdio.h>
int main()
{
	char buf[1024] = { 0 };
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		return 0;
	}
	fgets(buf, 1024, pf);
	puts(buf);
	fgets(buf, 1024, pf);
	puts(buf);

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

在这里插入图片描述
现在来看fputs
在这里插入图片描述
在这里插入图片描述

//fputs
#include<stdio.h>
int main()
{
	char buf[1024] = { 0 };
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		return 0;
	}
	//写文件
	fputs("hello\n", pf);
	fputs("world\n", pf);

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

在这里插入图片描述
我们知道fgets适用于所有输入流和fputs适用于所有输出流,所以请看:

//fgets和fputs
#include<stdio.h>
int main()
{
	//从键盘读取一行文本信息
	char buf[1024] = { 0 };
	fgets(buf, 1024, stdin);//从标准输入流读取
	fputs(buf, stdout);//从标准输出流读取

	return 0;
}

在这里插入图片描述

//fgets和fputs
#include<stdio.h>
int main()
{
	//从键盘读取一行文本信息
	char buf[1024] = { 0 };
	
	//fgets(buf, 1024, stdin);//从标准输入流读取
	//fputs(buf, stdout);//从标准输出流读取

	//上述写法等价于下面这种写法
	gets(buf);
	puts(buf);

	return 0;
}

在这里插入图片描述

格式化输入输出函数

我们刚刚读取的都是字符串,那现在我们能不能把一些有格式的一些数据写到文件里面去。就比如说结构体

fprintf

在这里插入图片描述

//fprintf:可以把格式化的信息放到文件中去
struct S
{
	int n;
	float score;
	char arr[10];
};
#include<stdio.h>
int main()
{
	struct S s = { 100,3.14f,"hello" };
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		return 0;
	}
	//格式化的形式写文件
	fprintf(pf, "%d %f %s", s.n, s.score, s.arr);

	fclose(pf);
	return 0;
}

在这里插入图片描述

fscanf

刚刚我们通过fprintf把格式化的信息放进文件中去了。那现在我们也可以通过fscanf把它拿出来。
在这里插入图片描述

//fscanf:可以把信息从文件中拿出来
struct S
{
	int n;
	float score;
	char arr[10];
};
#include<stdio.h>
int main()
{
	struct S s = { 0 };

	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		return 0;
	}
	//格式化的输入数据
	fscanf(pf, "%d %f %s", &s.n, &s.score, s.arr);
	printf("%d %f %s\n", s.n, s.score, s.arr);

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

在这里插入图片描述
现在我们已经通过格式化输入输出函数按照某一种格式来把数据写进去。当然这种格式可以是我们想要的某一种格式,我们完全可以做到想怎么把数据放进去就可以怎么把数据放进去。

注意

注意:格式化输入输出函数同样适用于所有输入流(fscanf)和所有输出流(fprintf)

struct S
{
	int n;
	float score;
	char arr[10];
};
#include<stdio.h>
int main()
{
	struct S s = { 0 };
	fscanf(stdin, "%d %f %s", &(s.n), &(s.score), s.arr);//从标准输入流-即从键盘上获取信息
	fprintf(stdout, "%d %f %s", s.n, s.score, s.arr);
	return 0;
}

在这里插入图片描述

对比一组函数

对比一组函数:

scanf/fscanf/sscanf
printf/fprintf/sprintf

struct S
{
	int n;
	float score;
	char arr[10];
};
#include<stdio.h>
int main()
{
	struct S s = { 100,3.14f,"abcdef" };
	//假设我们想把s里面的数据转换为字符串

	char buf[1024] = { 0 };

	sprintf(buf, "%d %f %s", s.n, s.score, s.arr);
	//sprintf函数有能力把结构体中的数据转换为字符串
	printf("%s", buf);
	return 0;
}

在这里插入图片描述
注意:这里打印出来我们看到的100已经不是100了,而是100转换为字符串的'1''0''0'
对于sprintf,我们已经看到sprintf函数的确有能力把结构体中的数据转换为字符串。
我们当然也可以从buf数组中提出来一个结构体数据。
请看:

struct S
{
	int n;
	float score;
	char arr[10];
};
#include<stdio.h>
int main()
{
	struct S s = { 100,3.14f,"abcdef" };
	struct S tmp = { 0 };

	char buf[1024] = { 0 };
	//把格式化的数据转换成字符串存储到buf
	sprintf(buf, "%d %f %s", s.n, s.score, s.arr);
	//printf("%s", buf);
	//从buf中读取格式化的数据到tmp
	sscanf(buf, "%d %f %s", &(tmp.n), &(tmp.score), tmp.arr);
	printf("%d %f %s\n", tmp.n, tmp.score, tmp.arr);
	return 0;
}

在这里插入图片描述
在这里插入图片描述

二进制输入和输出

fwrite

struct S
{
	char name[20];
	int age;
	double score;
};
#include<stdio.h>
int main()
{
	struct S s = { "张三",20,59 };
	FILE* pf = fopen("test.txt", "wb");
	if (pf == NULL)
	{
		return 0;
	}
	//二进制的形式写文件
	fwrite(&s, sizeof(struct S), 1, pf);
	fclose(pf);
	pf = NULL;
	return 0;
}

在这里插入图片描述
在这里插入图片描述

struct S
{
	char name[20];
	int age;
	double score;
};
#include<stdio.h>
int main()
{
	struct S s = { "张三",20,59 };
	FILE* pf = fopen("test.txt", "wb");
	if (pf == NULL)
	{
		return 0;
	}
	//二进制的形式写文件
	fwrite(&s, sizeof(struct S), 1, pf);
	fclose(pf);
	pf = NULL;
	return 0;
}

在这里插入图片描述
发现test.txt文件中的后半部分是乱码。原因就是因为我们是以二进制的方式把数据放进文件的
尽管我们肉眼看不懂二进制形式的文件,但是没关系,如果我们读文件中的信息是应该是可以读出来的。

fread

我们刚刚通过fwrite已经把数据以二进制的方式放进文件中去了,这个时候我们怎么读取文件呢?
在这里插入图片描述
在这里插入图片描述

//fread
struct S
{
	char name[20];
	int age;
	double score;
};
#include<stdio.h>
int main()
{
	//struct S s = { "张三",20,59.5 };
	struct S tmp = { 0 };
	FILE* pf = fopen("test.txt", "rb");
	if (pf == NULL)
	{
		return 0;
	}
	//二进制的形式读文件
	fread(&tmp, sizeof(struct S), 1, pf);
	printf("%s %d %lf\n", tmp.name, tmp.age, tmp.score);
	fclose(pf);
	pf = NULL;
	return 0;
}

在这里插入图片描述

文件的随机读写

前面我们学习的是文件的顺序读写,现在我们来介绍一下文件的随机读写
那什么是文件的随机读写呢?
我们使用fopen打开一个文件可以得到一个文件指针,这个文件指针也会被用于读写文件的时候。我们在读取一个文件的时候,文件指针指向下一个我们要读取的字符(一开始指向第一个字符),每当我们调用一次读取函数时,如 fgetc/fgets,这个文件指针就会向后移动一个或者多个单位。

fseek

在这里插入图片描述

在这里插入图片描述

//fseek
#include<stdio.h>
int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		return 0;
	}
	//定位文件指针
	fseek(pf, 2, SEEK_CUR);
	//读取文件
	int ch = fgetc(pf);
	printf("%c\n", ch);
	fclose(pf);
	pf = NULL;
	return 0;
}

在这里插入图片描述
在这里插入图片描述

ftell

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

例如:

//fseek
#include<stdio.h>
int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		return 0;
	}
	int pos = ftell(pf);//ftell返回文件指针相对于起始位值的偏移量
	printf("%d\n", pos);
	
	fclose(pf);
	pf = NULL;
	return 0;
}

在这里插入图片描述
默认打开时文件指针位于起始位置,此时相对于起始偏移量为0。
来看下一个代码:
在这里插入图片描述

rewind

让文件指针的位置回到文件的起始位置
void rewind( FILE * stream);
在这里插入图片描述
在这里插入图片描述

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

在这里插入图片描述

文件结束的判定

首先我们先要了解EOF是什么?

什么是EOF

在这里插入图片描述
当我们打开一个文件而里面什么都没有的时候:
在这里插入图片描述
我们第一次读到的就是EOF

#include<stdio.h>
int main()
{
	//EOF - end of file - 文件结束标志
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		return 0;
	}
	int ch = fgetc(pf);
	printf("%d", ch);
	fclose(pf);
	pf=NULL;
	return 0;
}

在这里插入图片描述

feof

关于feof函数经常会被错误的使用。
牢记:在文件读取过程中,不能使用feof函数的返回值直接用来判定文件的是否结束。而是应用于当文件读取结束的时候,判断到底是读取失败结束,还时遇到文件尾结束
判断文件是否读取结束方法如下:
1.文本文件读取是否结束,判断返回值是否为EOF(fget),或者NULL(fgets)
例如:

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

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

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

perror

在这里插入图片描述

//perror
#include<stdio.h>
int main()
{
	//sterror - 把错误码对应的错误信息的字符串地址返回
	//printf("%s\n", strerror(erron));

	//perror
	FILE* pf = fopen("test2.txt", "r");
	if (pf == NULL)
	{
		perror("hehe");
		return 0;
	}
	//读文件

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

在这里插入图片描述
函数perror直接会把你放过来的字符串先打印出来,打印一个,打印一个空格,再把前面发生这个错误的时候,错误码所对应的错误信息打印到后面去。
所以,函数perror与函数strerror相比会更加简单,因为perror函数不需要引用头文件,它自动会把errno,此时此刻被设置的errno里面的值所对应的错误信息打印出来,同时也更加直观
下面才是正确的使用实例:

请务必注意下面这幅图:
在这里插入图片描述
结合这段代码:

#include<stdio.h>
int main()
{
	int c;//注意:int,非char,要求处理EOF
	FILE* pf = fopen("test.txt", "r");
	if (!pf)
	{
		perror("File opening failed");
		return -1;
	}
	//fgetc 当读取失败的时候或者遇到文件结束的时候,都会返回EOF
	while ((c = fgetc(pf)) != EOF)
	{
		putchar(c);
	}
	//判断是什么原因结束的
	if (ferror(pf))
	{
		puts("I/0 error when reading");
	}
	else if (feof(pf))
	{
		puts("EOF of file reached successfully");
	}
	fclose(pf);
	return 0;
}

在这里插入图片描述

//二进制文件的例子
#include<stdio.h>
enum
{
	SIZE = 5
};
int main()
{
	double a[SIZE] = { 1.0,2.0,3.0,4.0,5.0 };
	double b = 0.0;
	size_t ret_code = 0;
	FILE* pf = fopen("test.txt", "wb");//必须用二进制格式
	fwrite(a, sizeof(*a), SIZE, pf);//写double的数组
	fclose(pf);

	pf = fopen("test.txt", "rb");
	//读double的数组
	while ((ret_code - fread(&b, sizeof(double), 1, pf)) >= 1)
	{
		printf("%lf\n", b);
	}
	if (feof(pf))
	{
		printf("EOF of file reached successfully");
	}
	else if (ferror(pf))
	{
		perror("Error reading test.txt");
	}
	fclose(pf);
	pf = NULL;
	return 0;
}

在这里插入图片描述

以上两段代码请务必记住并理解。
好了😚,C语言文件的操作就到这里吧。这块内容确实比较杂,函数的确好多好多😓。但全是满满的干货啊,这块内容大家一定要多上机实践,相信只要掌握了这块内容对自身C语言水平的提高就又上升到了一个档次。
感谢各位了!!!💕

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

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

相关文章

转轮除湿机空调系统运行时的故障排查SICOLAB

在现代科技不断发展的过程中&#xff0c;除湿技术已经应用到各个行业&#xff0c;尤其是在进行除湿空调系统设计时&#xff0c;因为相关系统的性能更加稳定且除湿量比较大、使用寿命更长、使用的设备比较简单&#xff0c;所以可以实现湿度的有效控制。 转轮除湿机空调系统在运…

【快速学习系列】SpringMVC的使用、传递参数(request、session、对象、集合...)及显示风格

【快速学习系列】SpringMVC的使用、传递参数&#xff08;request、session、对象、集合…&#xff09;及显示风格 SpringMVC扮演的角色就相当于Servlet的角色 Spring MVC框架特点 清晰地角色划分 灵活的配置功能 提供了大量的控制器接口和实现类 真正做到与View层的实现无关&…

手把手系列:如何将小程序游戏引入自有APP?(Android篇)

在上一期的手把手系列中为大家分享了&#xff1a;如何在iOS中引入FinClip SDK&#xff0c;并将小程序游戏运行到自有App 中。点击查看&#xff1a;&#x1f449;手把手系列&#xff1a;如何将小程序游戏引入自有APP&#xff1f;&#xff08;iOS篇&#xff09; 本周继续分享如何…

如何学习 Linux 内核网络协议栈

【推荐阅读】 深入linux内核架构--进程&线程 了解Docker 依赖的linux内核技术 怎么在Windows下使用Makefile文件 浅析linux内核网络协议栈--linux bridge 深入理解SR-IOV和IO虚拟化 协议栈的细节 下面将介绍一些内核网络协议栈中常常涉及到的概念. sk_buff 内核显…

Springboot集成Flyway(适用于多数据源)

1. Flyway 可以将初始化sql在项目启动时候执行&#xff0c;取代单独的DBN更新包 2. 依赖 <dependency><groupId>org.flywaydb</groupId><artifactId>flyway-core</artifactId><version>5.2.1</version> </dependency> 3. …

动作捕捉技术中分辨率和频率的重要性

对于光学动作捕捉设备来说&#xff0c;其核心产品——光学动作捕捉镜头&#xff0c;分为多种不同规格参数&#xff0c;本文将介绍其中影响光学动作捕捉设备效果的两个重要参数&#xff1a;分辨率与频率。 分辨率&#xff1a; 被捕捉的反光标记点在镜头画面中以像素形式呈现&a…

【JavaWeb】JSONAJAXi18n

文章目录一.JSON的使用1.在JavaScript中的使用2.在java中的使用二.AJAX请求1.AJAX请求2.原生AJAX请求实例3.jQuery中的AJAX请求三.i18n1.概念2.国际化三要素3.国际化资源properties测试4.实现国际化JSON是一种轻量级的数据交换格式,易于人们阅读和编写,同时也易于机器解析和生成…

2022年网络安全比赛--压缩包文件暴力破解中职组(超详细)

2022年比赛压缩包文件暴力破解解析 一、竞赛时间 180分钟 共计3小时 二、竞赛阶段 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 1.通过本地PC中渗透测试平台Kali使用Nmap扫描目标靶机服务版本信息,将 Telnet 版本信息字符串作为 Flag 提交; 2. 通过本地PC中渗透测试平台Kali对…

Odoo 16 企业版手册 - 采购之代发货

代发货(直运) 待发货方式是不打算保留库存的供应商可用的便捷运输方式之一。此方法将允许您将产品直接从供应商运送到客户。这对零售商更有利&#xff0c;因为交货直接从供应商到客户&#xff0c;没有必要保留仓库。直接发货方法将帮助您直接从供应商或制造商将产品运送给客户&…

设计模式概述之抽象工厂模式(三)

上次咱们说了工厂方法模式&#xff0c;不知道各位同学掌握了没有。今天咱们说说“抽象工厂模式”。 抽象工厂&#xff08;AbstractFactory&#xff09;模式的定义&#xff1a;是一种为访问类提供一个创建一组相关或相互依赖对象的接口&#xff0c;且访问类无须指定所要产品的具…

计算机网络——CSMA-CA协议

CSMA-CD协议是对碰撞的检测&#xff0c;CSMA-CA协议是对碰撞的避免 CSMA-CD和CSMA-CA应用场景不一样&#xff0c;CSMA-CA协议主要用于无线局域网&#xff0c;CSMA-CD应用与总线式以太网。 无线局域网用CSMA-CD协议无法做到360检测碰撞 隐蔽站&#xff1a;A和C都检测不到信号&am…

Oracle---视图

Oracle之视图和物化视图 文章目录Oracle之视图和物化视图视图优点创建视图带检查约束视图只读视图创建带错误的视图删除视图查询视图物化视图&#xff08;实体化视图&#xff09;区别和优点创建物化视图创建手动刷新的物化视图执行下列语句刷新创建自动刷新的物化视图创建时不生…

Java日志框架简介

一、java日志发展线路图 上面涵盖了java世界里主要的日志框架或门面 二、日志门面和框架的区别 日志框架技术 JUL、Logback、Log4j、Log4j2 用来方便有效地记录日志信息 日志门面技术 JCL、SLF4j 为什么要使用日志门面技术&#xff1a; 每一种日志框架都有自己单独的API&am…

[附源码]Python计算机毕业设计高校学生管理系统Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等…

自学一个月pyhon找到工作,半年成为多个平台关注破万的小作者

前言 干货来了&#xff0c;浓缩了我学习python的所有学习经历&#xff0c;从中获取到的经验分享给你&#xff0c;如果你看了没用&#xff0c;那让我打你一拳。 大学 高中的我&#xff0c;考了三次高考才勉强考上一个二本大学一本数学专业&#xff0c;你没听错&#xff0c;三…

基于C语言实现(控制台)学生成绩管理系统【100010051】

学生成绩管理系统 说明&#xff1a; 注册密码&#xff1a;2014052421程序包含中文和特殊字符&#xff0c;在 Window 下需 ASCII 编码&#xff0c;不能 UTF-8 编码。程序对三个文件要求是文本文件&#xff0c;且 studata.txt 中包含中文字符&#xff0c;在 window 下也需要 AS…

全网惟一面向软件测试人员的Python基础教程-在Python中如何优雅的切西瓜呢?

全网惟一面向软件测试人员的Python基础教程 起点&#xff1a;《python软件测试实战宝典》介绍 第一章 为什么软件测试人员要学习Python 第二章 学Python之前要搞懂的道理 第三章 你知道Python代码是怎样运行的吗&#xff1f; 第四章 Python数据类型中有那些故事呢&#xff1f;…

第03讲:Security之用户鉴权

一、创建项目 参考&#xff1a;浅试Security 二、实现用户鉴权 何为鉴权&#xff1f;说白了其实就是用户认证&#xff0c;用户输入用户名和密码&#xff0c;只有认证通过了才能使用我的系统。 在实际的项目开发中&#xff0c;账号和密码都是从数据库中查询出来的。所…

820爆炸案(模拟案件)

文章目录模拟案件背景相关密码快压word邮箱BitLocker系统证书bestcrypt涉案图片模拟案件背景 8月20日18&#xff1a;00某市汽车站发生一起爆炸案件&#xff0c;经初步侦查&#xff0c;炸弹系通过手机远程引爆&#xff0c;办案人员经过综合研判分析&#xff0c;确定了引爆炸弹的…

在Mac电脑上怎么修改移动硬盘的读写权限?怎样修改mac电脑中移动硬盘的权限

在Mac电脑上怎么修改移动硬盘的读写权限&#xff1f;你是否遇到过把外部硬盘连接到Mac电脑后&#xff0c;外部硬盘只能读取不能写入的问题&#xff1f;大部分的情况是因为硬盘格式可能是Windows系统的格式&#xff0c;导致在mac电脑上只能读取不能写入。那我们要怎么才能正常的…