深入C语言:文件操作实现局外影响程序

news2024/12/26 16:14:37

一、什么是文件

文件其实是指一组相关数据的有序集合。这个数据集有一个名称,叫做文件名。文件通常是驻留在外部介质(如磁盘等)上的,在使用时才调入内存中来。

文件一般讲两种:程序文件和数据文件:

  • 程序文件:包括源程序文件(后缀为.c),目标文件(windows环境后缀为.obj),可执行程序(windows环境后缀为.exe)。
  • 数据文件:包括程序运行时所读写的数据。本篇所涉及的就是数据文件。

二、文件的使用

文件的操作一般分三步:1.打开文件;2.读/写;3.关闭文件;

三、文件的打开与关闭

3.1 流与标准流

在C语言中,“流”(stream)是一种用于输入和输出数据的抽象概念,我们可以把流想象成流淌着字符的河。它是一种数据的传输方式,可以将数据从一个地方传送到另一个地方。在C语言中,输入流和输出流是通过一组标准库函数来实现的,这些函数允许程序从键盘或文件中读取数据,或者将数据写入到屏幕或文件中

C程序针对文件、画面、键盘等数据输⼊输出操作都是通过流操作的。⼀般情况下,我们要想向流⾥写数据,或者从流中读取数据,都是要打开流,然后操作。

C语言中的流可以分为标准流(standard streams)文件流(file streams)

注:C语言中操作流的主要函数是标准I/O库中的stdio.h头文件中定义的函数。

3.1.1 标准流

我们需要清楚,C语言程序,只要运行起来,就会默认打开3个流(标准流)

标准输入流(stdin):用于读取输入数据,默认情况下是键盘输入。
标准输出流(stdout):用于向终端或命令行窗口输出数据。
标准错误流(stderr):用于输出错误信息。

3.1.2 文件流

C语言中的文件流是一种用于在程序中读取和写入文件的流。通过文件流,可以在C程序中打开文件,从文件中读取数据或将数据写入文件中。这样可以有效地处理大量数据、持久性存储以及与文件系统的交互。

本次,我们重点讨论文件流

3.2 文件指针

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

文件指针的使用方式:

    FILE* pf;

 定义一个文件指针变量pf,它可以指向某个文件的文件信息区,通过其即可访问到该文件。

3.3 文件的打开与关闭

⽂件在读写之前应该先打开⽂件,在使⽤结束之后应该关闭⽂件,在编写程序的时候,在打开⽂件的同时,都会返回⼀个FILE*的指针变量指向该⽂件,也相当于建⽴了指针和⽂件的关系。

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

FILE * fopen ( const char * filename, const char * mode );	//打开文件
int fclose ( FILE * stream );	//关闭文件

3.3.1 文件的访问方式

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

注1:当文件打开失败出错时,会返回一个空指针,因此我们一定要在打开文件之后,对文件指针进行有效性检查
注2:对于打开进行更新的文件(包含“+”号的文件),允许输入和输出操作,在写入操作之后的读取操作之前,应刷新(fflush)或重新定位流(fseek,fsetpos,rewind)。流应在读取操作之后的写入操作之前重新定位(fseek、fsetpos、rewind)(只要该操作未到达文件末尾)

3.4 文件的使用方式

代码示例如下:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

int main()
{
    //此时该路径下没有名为data.txt的文件,因此会打开失败
	FILE* fp = fopen("data.txt", "r");
	if (NULL == fp)
	{
		perror("fopen");
		return 1;
	}

	fclose(fp);
	fp = NULL;

	return;
}

#include<stdio.h>

int main()
{
    //用写的方式打开文件,如果文件不存在,会在该路径底下创建一个新的名为data.txt的文件
	FILE* fp = fopen("data.txt", "w");
	if (NULL == fp)
	{
		perror("fopen");
		return 1;
	}

	fclose(fp);
	fp = NULL;

	return;
}

四、文件的顺序读写

顺序读写的函数:

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

4.1 单字符输入输出

(一)fputc函数

#include<stdio.h>
int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror(" fopen fail");
		return 1;
	}
    //将abc放进文件
	fputc('a', pf);
	fputc('b', pf);
	fputc('c', pf);
	//关闭文件
	fclose(pf);
	pf = NULL;//防止野指针
	return 0;
}

(二)fgetc函数

#include<stdio.h>
int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "r");//只读
	if (pf == NULL)
	{
		perror(" fopen fail");
		return 1;
	}
	fputc('a', pf);
	fputc('b', pf);
	fputc('c', pf);
	int ch = fgetc(pf);
	printf("读出来的字符为:%c\n", ch);
	ch = fgetc(pf);
	printf("读出来的字符为:%c\n", ch);
	ch = fgetc(pf);
	printf("读出来的字符为:%c\n", ch);
	//关闭文件
	fclose(pf);
	pf = NULL;//防止野指针
	return 0;
}

4.2 文本行输入输出

(一)fputs函数

#include<stdio.h>
int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror(" fopen fail");
		return 1;
	}
	fputs("hello betty", pf);
	//关闭文件
	fclose(pf);
	pf = NULL;//防止野指针
	return 0;
}

 

(二)fgets函数

  1. 声明:char *fgets(char *str, int n, FILE *stream)
    1. str – 这是指向一个字符数组的指针,该数组存储了要读取的字符串。
    2. n – 这是要读取的最大字符数(包括最后的空字符)。通常是使用以 str 传递的数组长度。
    3. stream – 这是指向 FILE 对象的指针,该 FILE 对象标识了要从中读取字符的流。
  2. 作用:从指定的流 stream 读取一行,并把它存储在 str 所指向的字符串内。当读取 (n-1) 个字符时,或者读取到换行符时,或者到达文件末尾时,它会停止,具体视情况而定。
  3. 返回值:如果成功,该函数返回相同的 str 参数。如果到达文件末尾或者没有读取到任何字符,str 的内容保持不变,并返回一个空指针。如果发生错误,返回一个空指针。
#include<stdio.h>
int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror(" fopen fail");
		return 1;
	}
	fputs("hello betty", pf);
	char arr[] = "##########";
	fgets(arr, 5, pf);
	puts(arr);
	//关闭文件
	fclose(pf);
	pf = NULL;//防止野指针
	return 0;
}

为什么只有四个字符呢 ,我们打开调试,会发现/0也要算一个字符

4.3 格式化输入输出

(一)fscanf函数

typedef struct student {
	char name[20];
	int height;
	float score;
}stu;
int main()
{
	stu s = { "beidi", 170, 95.0 };
	//写文件
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror(" fopen fail");
		return 1;
	}
	fprintf(pf, "%s %d %f", s.name, s.height, s.score);
	//关闭文件
	fclose(pf);
	pf = NULL;//防止野指针
	return 0;
}

(二)fprintf函数

typedef struct student {
	char name[20];
	int height;
	float score;
}stu;
int main()
{
	stu s = { "beidi", 170, 95.0 };
	//写文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror(" fopen fail");
		return 1;
	}
	fscanf(pf, "%s %d %f", s.name, &(s.height), &(s.score));
	printf("%s %d %f", s.name, s.height, s.score);
	//关闭文件
	fclose(pf);
	pf = NULL;//防止野指针
	return 0;
}

4.4 二进制输入输出

(一)fread函数

typedef struct student {
	char name[20];
	int height;
	float score;
}stu;
int main()
{
	stu s = { "beidi", 170, 95.0 };
	//写文件
	FILE* pf = fopen("test.txt", "wb");//二进制写入
	if (pf == NULL)
	{
		perror(" fopen fail");
		return 1;
	}
	fwrite(&s, sizeof(s), 1, pf);
	//关闭文件
	fclose(pf);
	pf = NULL;//防止野指针
	return 0;
}

二进制语言人类无法识别,但电脑能准确读取

(二)fwrite函数

typedef struct student {
	char name[20];
	int height;
	float score;
}stu;
int main()
{
	stu s = {0};
	//写文件
	FILE* pf = fopen("test.txt", "rb");//二进制写出
	if (pf == NULL)
	{
		perror(" fopen fail");
		return 1;
	}
	fread(&s, sizeof(s), 1, pf);
	printf("%s %d %f", s.name, s. height, s.score);
	//关闭文件
	fclose(pf);
	pf = NULL;//防止野指针
	return 0;
}

4.5 补充

sscanf和sprintf函数

typedef struct student {
	char name[20];
	int height;
	float score;
}stu;
 
int main()
{
	char buf[100] = { 0 };
	stu s = { "betty", 170, 95.0f };
	stu tmp = { 0 };
	//将这个结构体的成员转化为字符串
	sprintf(buf, "%s %d %f", s.name, s.height, s.score);
	printf("%s\n", buf);
	//将这个字符串中内容还原为一个结构体数据呢
	sscanf(buf, "%s %d %f", tmp.name, &(tmp.height), &(tmp.score));
	printf("%s %d %f", tmp.name, tmp.height, tmp.score);
	return 0;
}

五、文件的随机读写

所谓的随机读写,其实就是指定我们想要读写的位置

5.1 fseer()函数

  • 该函数可以从定位位置的偏移量处开始读写;
  • int fseek( FILE *stream, long offset, int origin );
                         文件流          偏移量    起始位置 
  • 返回值:
    1. 如果成功,fseek返回0;
    2. 否则,它返回一个非零值;
    3. 在无法查找的设备上,返回值未定义;     

使用实例:

int main()
{
	//打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror(" fopen fail");
		return 1;
	}
	fseek(pf, 4, SEEK_SET);
	//从起始位置偏移四个字节
	int ch1 = fgetc(pf);
	printf("%c ", ch1);
	fseek(pf, -3, SEEK_END);
	//从结束位置偏移七个个字节
         int ch2 = fgetc(pf);
	printf("%c ", ch2);
	fseek(pf, 1, SEEK_CUR);
	//从当前位置偏移一个字节
	int ch3 = fgetc(pf);
	printf("%c ", ch3);
	//关闭文件
	fclose(pf);
	pf = NULL;//防止野指针
	return 0;
}

 

5.2 ftell()函数

  1. 头文件:#include<stdio.h>
  2. 声明:long int ftell(FILE *stream)
    • stream – 这是指向 FILE 对象的指针,该 FILE 对象标识了流。
  3. 作用:返回⽂件指针相对于起始位置的偏移量
  4. 返回值:该函数返回位置标识符的当前值。如果发生错误,则返回 -1L,全局变量 errno 被设置为一个正值。

我们可以利用fseek和ftell来计算文件的长度(不包含’\0’),下列是代码示例

int main()
{
	FILE* pFile;
	long size;
	pFile = fopen("test.txt", "rb");
	if (pFile == NULL) 
		perror("Error opening file");
	else
	{
		fseek(pFile, 0, SEEK_END); //non-portable
		size = ftell(pFile);
		fclose(pFile);
		printf("文件长度为: %ld bytes.\n", size);
	}
	return 0;
}

5.3 rewind()函数

  1. 头文件:#include<stdio.h>
  2. 声明:void rewind(FILE *stream)
    • stream – 这是指向 FILE 对象的指针,该 FILE 对象标识了流
  3. 作用:让⽂件指针的位置回到⽂件的起始位置
  4. 返回值:该函数不返回任何值。

rewind常常在文件读与写同时使用时,以方便文件读取。下面是rewind的具体使用实例:

#include <stdio.h>
int main()
{
	int n;
	FILE* pFile;
	char buffer[27];
	pFile = fopen("myfile.txt", "w+");
	for (n = 'A'; n <= 'Z'; n++)
		fputc(n, pFile);//放入26个字母
	rewind(pFile);//回到起始位置,方便读取
	fread(buffer, 1, 26, pFile);//读取·
	fclose(pFile);
	buffer[26] = '\0';//字符串的结束标识
	printf(buffer);
	return 0;
}

六、二进制文件与文本文件

我们知道数据在内存中是以二进制形式存储的,对于文件而言:如果不加转换直接输出到外存就是二进制文件;如果要在外存上以ASCII码形式存储,就需要提前转换最后以ASCII码值形式存储的文件就是文本文件。

对于字符,一律使用ASCII码形式存储,但对于数值型数据,即可以使用ASCII码存储也可以使用二进制形式存储。

举例:

数字10000的两种存储形式:

二进制文件:

文本文件:

首先将10000分成'1','0','0','0','0', 这五个字符,用每个字符对应的ASCII码值进行转换:

显而易见,二进制文件存储和文本文件存储对不同范围的数字可以做到节省空间。

七、文件读取结束判定

feof()函数:该函数被许多人错误用来判断文件是否读取结束,其实它的作用是判断文件读取结束的原因;

文件读取结束有两种情况:1.读取过程中出现异常; 2.读取到文件末尾;

要找出文件读取是哪个原因,就分为以下情况:

文本文件:

  • 如果用 fgetc() 读取,要判断 feof() 的返回值是否为EOF;
  • 如果用 fgets() 读取,要判断 feof() 的返回值是否为NULL(0);

二进制文件:

        都是使用 fread() 读取,要判断其返回值与指定读取个数的大小,如果小于实际要读的个数,就说明发生读取异常,如果等于实际要读的个数,就说明是因读取成功而结束;

对于读取异常的判断,我们考虑判断 ferror() 函数的返回值:

  1. 若ferrror()为真——异常读取而结束;
  2. 若feof()为真——正常读取到尾而结束;

对文本文件的判断:

#include<stdio.h>
#include<string.h>
#include<errno.h>
 
int main()
{
	FILE* pf = fopen("test.txt", "r");
 
	if (pf == NULL)
	{
		perror("fopen is failed !");
		return;
	}
	int c = 0;
	//由于要检查EOF——EOF本质是0——所以是int
	while (c = fgetc(pf) != EOF)
	{
		putchar(c);
	}
	//直到while不执行了—读取结束了—判断是什么原因结束的
	if (ferror(pf))
	{
		printf("读取中出现错误\n");
	}
	else if (feof(pf))
	{
		printf("读取到文件尾\n");
	}
 
	fclose(pf);
	pf = NULL;
 
	return 0;
}

对二进制文件的判断:

#include<stdio.h>
#include<string.h>
#include<errno.h>
 
int main()
{
	FILE* pf = fopen("test.txt", "rb");
	int arr[5] = { 0 };
 
	if (pf == NULL)
	{
		return;
	}
 
	size_t num = fread(arr, sizeof(int), 5, pf);
 
	if (num == 5)
	{
		//说明全部读取成功
		printf("Array read successfully\n");
	}
	else
	{
		//说明读取不够指定长度—判断是什么原因
		if (ferror(pf))
		{
			printf("读取中出现错误\n");
		}
		else if (feof(pf))
		{
			printf("读取到文件尾\n");
		}
	}
 
	fclose(pf);
	pf = NULL;
 
	return 0;
}

八、文件缓冲区

ANSIC 标准采用缓冲文件系统处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每一个正在使用的文件开辟一块“文件缓冲区”。

  • 从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才⼀起送到磁盘上。
  • 如果从磁盘向计算机读⼊数据,则从磁盘⽂件中读取数据输⼊到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)
  • 缓冲区的⼤⼩根据C编译系统决定的。
include <stdio.h>
#include <windows.h>
//VS2019 WIN11环境测试
int main()
{
	FILE* pf = fopen("test.txt", "w");
	fputs("abcdef", pf); //先将代码放在输出缓冲区
	printf("睡眠10秒-已经写数据了,打开test.txt⽂件,发现⽂件没有内容\n");
	Sleep(10000);
	printf("刷新缓冲区\n");
	fflush(pf); //刷新缓冲区时,才将输出缓冲区的数据写到⽂件(磁盘)
	//注:fflush 在⾼版本的VS上不能使⽤了
	printf("再睡眠10秒-此时,再次打开test.txt⽂件,⽂件有内容了\n");
	Sleep(10000);
	fclose(pf);
	//注:fclose在关闭⽂件的时候,也会刷新缓冲区
	pf = NULL;
	return 0;
}

因为有缓冲区的存在,C语⾔在操作⽂件的时候,需要做刷新缓冲区或者在⽂件操作结束的时候关闭⽂件。如果不做,可能导致读写⽂件的问题。

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

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

相关文章

模拟IC设计实践教程(入门)

一、教学大纲 二、芯片设计及量产总体流程 芯片需求分析&#xff1a;即产品定义&#xff0c;功能要求&#xff0c;性能要求工艺选择及评估&#xff1a;不同工艺特性相差较大&#xff0c;不同工艺的成本也是不同的。主要用于评估工艺的性价比&#xff0c;工艺提供的元器件能不能…

pip install 过程中报错:Microsoft Visual C++ 14.0 is required.

这是因为电脑中缺少这个组件导致的,我们将这个组件安装上即可解决问题。 安装报错关键信息:Microsoft Visual C++ 14.0 is required. 目录 一、下载组件 二、 安装步骤 一、下载组件 阿里网盘:VisualStudioSetup.exe:

绝地求生:季后赛名额确定!NH战队总积分榜排名第一!

2024年5月5日&#xff0c;PCL春季赛常规赛第五阶段第三天比赛结束&#xff0c;今天打完春季赛常规赛结束&#xff0c;16个战队进入季后赛的名额已确定。NH战队总积分506分&#xff0c;总积分榜排名第一&#xff01;&#xff01;NH战队也是唯一一支总积分超过500分的队伍。今天最…

LabVIEW自动机械变速器(AMT)开发

LabVIEW自动机械变速器&#xff08;AMT&#xff09;开发 在现代汽车工业中&#xff0c;提升车辆的自动化水平和驾驶体验是一个不断追求的目标。随着技术的发展&#xff0c;自动机械变速器&#xff08;AutomatedMechanical Transmission, AMT&#xff09;凭借其较高的能效和较低…

详解嵌入式MCU运行时分配的stack和heap

目录 概述 1 认识stack和heap 1.1 栈区&#xff08;stack&#xff09; 1.2 堆区&#xff08;heap&#xff09; 2 stack和heap的区别 2.1 管理方式的不同 2.2 空间大小不同 2.3 产生碎片不同 2.4 增长方式不同 2.5 分配方式不同 2.6 分配效率不同 3 确定stack和heap…

细数:智能物流装备界的并购案~

导语 大家好&#xff0c;我是智能仓储物流技术研习社的社长&#xff0c;老K。专注分享智能仓储物流技术、智能制造等内容。 新书《智能物流系统构成与技术实践》 近年来&#xff0c;随着智能仓储物流行业的快速发展&#xff0c;全球范围内的并购活动日益频繁&#xff0c;各大企…

Hamilton回路求解

如果可以 我想和你回到那天相遇 让时间停止 那一场雨 红线划过 深藏轮回的秘密 我挥霍运气 因为你 才让我 背对命运不害怕 --------- 如果可以 (Acapella) - 韦礼安 大家好&#xff0c;我又又又来了&#xff0c;今天给大家聊聊Hamilton回路&#xff01; 背景 国际象…

VSCode通过SSH连接虚拟机Ubuntu失败

问题说明 最近使用VSCode通过SSH连接Ubuntu&#xff0c;通过VSCode访问Ubuntu进行项目开发&#xff0c;发现连接失败 在VSCode中进行SSH配置 这些都没有问题&#xff0c;但在进行连接时候出现了问题&#xff0c;如下&#xff1a; 出现了下面这个弹窗 解决方法 发现当…

从简单逻辑到复杂计算:感知机的进化与其在现代深度学习和人工智能中的应用(上)

文章目录 引言第一章&#xff1a;感知机是什么第二章&#xff1a;简单逻辑电路第三章&#xff1a;感知机的实现3.1 简单的与门实现3.2 导入权重和偏置3.3 使用权重和偏置的实现实现与门实现与非门和或门 文章文上下两节 从简单逻辑到复杂计算&#xff1a;感知机的进化与其在现代…

与 Apollo 共创生态:Apollo 7 周年大会的启示与心得

文章目录 前言Apollo X 全新征程Application X 企业预制套件总结 前言 在过去的七年中&#xff0c;Apollo 开放平台经历了一段令人瞩目的发展历程。从最初的构想到如今的成熟阶段&#xff0c;Apollo 已经推出了 13 个版本&#xff0c;吸引了来自全球 170 多个国家和地区的 16 …

python 中的数据结构

python 中的数据结构 1.1 序列 序列时有索引的数组 举例实现&#xff1a; a["北京","上海","广州","深圳","重庆","成都"] print(a[2]) print(a[-1] " " a[-2]) print(a[1:3]) # 运行结果 "&…

Java设计模式 _结构型模式_外观模式

一、外观模式 1、外观模式 外观模式&#xff08;Facade Pattern&#xff09;是一种结构型模式。主要特点为隐藏系统的复杂性&#xff0c;并向客户端提供了一个客户端可以访问系统的接口。这有助于降低系统的复杂性&#xff0c;提高可维护性。当客户端与多个子系统之间存在大量…

使用Zotero自定义参考文献格式的教程

Zotero Zotero是一个开源的参考文献管理软件&#xff0c;它能够帮助研究人员和学生收集、管理和引用各种来源的文献&#xff0c;包括书籍、期刊文章、网页、图片等。用户可以使用Zotero将文献信息直接保存到自己的库中&#xff0c;并且可以根据需要创建标签、注释和文件夹来组…

Go实现树莓派控制舵机

公式说明 毫秒&#xff08;ms&#xff09;是时间的单位&#xff0c;赫兹&#xff08;Hz&#xff09;是频率的单位&#xff0c;而DutyMax通常是一个PWM&#xff08;脉冲宽度调制&#xff09;信号中表示最大占空比的值。以下是它们之间的关系和一些相关公式&#xff1a; 频率&…

软件测试与管理:黑盒测试-因果图法和场景法

知识思维导图&#xff1a; ​​​​​​​ 例题1&#xff1a;运用因果图法设计测试用例 有一个处理单价为5角钱的饮料的自动售货机软件测试用例的设计。其规格说明如下&#xff1a; 若投入5角钱或1元钱的硬币&#xff0c;按下〖橙汁〗或〖啤酒〗的按钮&#xff0c;则相应的饮料…

XSS-Labs 靶场通过解析(上)

前言 XSS-Labs靶场是一个专门用于学习和练习跨站脚本攻击&#xff08;XSS&#xff09;技术的在线平台。它提供了一系列的实验场景和演示&#xff0c;帮助安全研究人员、开发人员和安全爱好者深入了解XSS攻击的原理和防御方法。 XSS-Labs靶场的主要特点和功能包括&#xff1a;…

C++字模软件发送 单片机接收显示

/****先定义数组类型再赋值**L310*********/ /*2014 8 21 10:01**PAST*CODE1000**TEST**/ #include<reg51.h> #define uint unsigned int #define uchar unsigned char sfr AUXR0x8e; //辅助寄存器 sfr SADDR0xA9; …

后台启动HIVE的JDBC连接

后台启动HIVE的JDBC连接 生活就像一杯咖啡&#xff0c;有时苦涩&#xff0c;有时香甜&#xff0c;但都是值得品味的经历。无论遇到什么挑战&#xff0c;记住在每一天的开始&#xff0c;你都有机会给自己倒上一杯清新的力量&#xff0c;为心灵添一抹温暖。勇敢地面对生活的苦与甜…

aardio爬虫) 实战篇:逆向有道翻译web接口

前言 之前的文章把js引擎(aardio封装库) 微软开源的js引擎(ChakraCore))写好了&#xff0c;这篇文章整点js代码来测一下bug。测试网站&#xff1a;https://fanyi.youdao.com/index.html#/ 逆向思路 逆向思路可以看有道翻译js逆向&#xff08;MD5加密&#xff0c;AES加密&…

Ubuntu上使用audit2allow解决Android Selinux问题

1.安装工具 sudo apt install policycoreutils 2.运行命令 提前用dmesg或者串口抓取kernel log 遇到错误&#xff0c;提示需要用-p指定policy file&#xff0c;然偶尝试创建一个policy空文件&#xff0c;用-p选项&#xff0c;遇到如下错误 3.规避问题 首先跟进错误log的堆栈…