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

一、什么是文件

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

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

  • 程序文件:包括源程序文件(后缀为.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语⾔在操作⽂件的时候,需要做刷新缓冲区或者在⽂件操作结束的时候关闭⽂件。如果不做,可能导致读写⽂件的问题。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Android Studio实现简单的自定义钟表

项目目录 一、项目概述二、开发环境三、详细设计3.1、尺寸设置3.2、绘制表盘和指针3.3、动态效果 四、运行演示五、总结展望六、源码获取 一、项目概述 在安卓开发中&#xff0c;当系统自带的View已经无法满足项目需求时&#xff0c;就要自定义View。在Android中是没有与钟表有…

Linux PXE高效批量网络装机

系统初始化 systemctl disable --now firewalld.service setenforce 0 vim /etc/selinux/config 安装软件 yum install -y tftp-server xinetd dhcp vsftpd syslinux 复制 vmlinuz initrd.img pxelinux.0 到 /var/lib/tftpboot/ 目录 [rootlocalhost ~]# cd /mnt/…

OWASP 发布开源软件OSS的十大风险,已知漏洞排名第一,首次汇齐了10大类型的攻击案例

尽管软件供应链严重依赖开源软件&#xff0c;但业界缺乏一致的方法来理解和衡量开源软件的风险。 OSS&#xff08;Open Source Sofware&#xff0c;开源软件&#xff09;的风险管理从许可证管理开始&#xff0c;然后发展到CVE&#xff0c;但我们仍然缺乏涵盖安全、法律和运营方…

Java请求第三方接口的一些步骤

一、前言 Java请求第三方接口的一些步骤。 在Java中请求第三方接口通常涉及以下步骤。这些步骤涵盖了从准备请求到处理响应的整个过程。 1. 确定接口详情 接口URL&#xff1a;你要请求的URL。请求方法&#xff1a;如GET、POST、PUT、DELETE等。请求参数&#xff1a;包括URL…

git tag 相关操作

文章目录 前言一、git里面的Tag二、Tag 类型1. 轻量级标签&#xff08;Lightweight Tag&#xff09;2. 注释标签&#xff08;Annotated Tag&#xff09; 其他常用操作git taggit show <tagname>git push origin <tagname>删除tag使用 gitk 查看效果 总结 前言 一般…

SparkSQL编程入口和模型与SparkSQL基本编程

SparkSQL编程入口和模型 SparkSQL编程模型 主要通过两种方式操作SparkSQL&#xff0c;一种就是SQL&#xff0c;另一种为DataFrame和Dataset。 1)SQL&#xff1a;SQL不用多说&#xff0c;就和Hive操作一样&#xff0c;但是需要清楚一点的是&#xff0c;SQL操作的是表&#xf…

Day_1

1. 环境搭建 技术选型 后端项目结构 sky-take-out maven父工程&#xff0c;统一管理依赖版本&#xff0c;聚合其他子模块 sky-common 子模块&#xff0c;存放公共类&#xff0c;例如&#xff1a;工具类、常量类、异常类等 sky-pojo 子模块&#xff0c;存放实体类、VO、DTO…

【UE5学习笔记】编辑及运行界面:关闭眼部识别(自动曝光)

自动曝光&#xff0c;也就是走进一个黑暗的环境&#xff0c;画面会逐渐变量&#xff0c;以模拟人眼进入黑暗空间时瞳孔放大&#xff0c;进光量增加的一种真实视觉感受&#xff1a; 制作过程中是否关闭自动曝光&#xff0c;取决于游戏的性质&#xff0c;但是个人认为&#xff0c…

力扣每日一题115:不同的子序列

题目 困难 给你两个字符串 s 和 t &#xff0c;统计并返回在 s 的 子序列 中 t 出现的个数&#xff0c;结果需要对 109 7 取模。 示例 1&#xff1a; 输入&#xff1a;s "rabbbit", t "rabbit" 输出&#xff1a;3 解释&#xff1a; 如下所示, 有 3 种…

遥遥领先们赚钱的路子,被香飘飘找到了……?

刚刚结束了的五一长假&#xff0c;中文互联网上可以说满是各种对立、冲突。 让人惋惜的胖猫及遭万人唾弃的捞女谭竹之外&#xff0c;曾经卖奶茶杯子绕地球几圈&#xff0c;如今却被多数人遗忘的香飘飘&#xff0c;一通操作下来&#xff0c;让不少吃瓜群众小刀剌屁股开了眼了……

自动化运维工具-Ansible

一、Ansible概述 Ansible是一种基于python开发的自动化运维工具&#xff0c;它只需要在服务端安装ansible&#xff0c;无需在每个客户端安装客户端程序&#xff0c;通过ssh的方式来进行客户端服务器的管理&#xff0c;基于模块来实现批量数据配置、批量设备部署以及批量命令执…

《Video Mamba Suite》论文笔记(4)Mamba在时空建模中的作用

原文翻译 4.4 Mamba for Spatial-Temporal Modeling Tasks and datasets.最后&#xff0c;我们评估了 Mamba 的时空建模能力。与之前的小节类似&#xff0c;我们在 Epic-Kitchens-100 数据集 [13] 上评估模型在zero-shot多实例检索中的性能。 Baseline and competitor.ViViT…

练习题(2024/5/5)

1左叶子之和 给定二叉树的根节点 root &#xff0c;返回所有左叶子之和。 示例 1&#xff1a; 输入: root [3,9,20,null,null,15,7] 输出: 24 解释: 在这个二叉树中&#xff0c;有两个左叶子&#xff0c;分别是 9 和 15&#xff0c;所以返回 24示例 2: 输入: root [1] 输…

【Web漏洞指南】XSS漏洞详细指南

【Web漏洞指南】XSS漏洞详细指南 概述XSS的三种类型执行任意 JS 代码的方式在原始HTML中注入绕过手法在 HTML标记内注入绕过手法在JavaScript代码中注入绕过手法其他绕过手法XSS常见有效载荷检索Cookies窃取页面内容键盘记录器查找内部IP地址端口扫描器自动填充密码捕获窃取 Po…

基于Spring Boot的大学生社团活动平台设计与实现

基于Spring Boot的大学生社团活动平台设计与实现 开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/idea 系统部分展示 前台首页功能界面图&#xff0c;学生在大学生社团…

Android11 InputManagerService启动流程分析

InputManagerService在systemserver进程中被启动 //frameworks\base\services\java\com\android\server\SystemServer.java t.traceBegin("StartInputManagerService"); inputManager new InputManagerService(context);//1 t.traceEnd(); //省略 //注册服务 Servi…

某东抢购某台脚本-低调

某东抢购某台脚本 小白操作-学习使用 注意&#xff1a; 本文部分变量已做脱敏处理&#xff0c;仅用于测试和学习研究&#xff0c;禁止用于商业用途&#xff0c;不能保证其合法性&#xff0c;准确性&#xff0c;完整性和有效性&#xff0c;请根据情况自行判断。技术层面需要提…

尊享面试100(272.最接近的二叉树搜索值|| python)

刚开始想着用最小堆&#xff0c;把每个元素都加进去&#xff0c;然后找出最小的k个值&#xff0c;复杂度应该是&#xff08;nklogn) import heapq as pq class Solution:def __init__(self):self.h []pq.heapify(self.h)def closestKValues(self, root: Optional[TreeNode], …

WINDOWS配置IIS

1.安装IIS 1.1.打开启用Windows功能 打开“控制面板” > “程序和功能” > “启用或关闭 Windows 功能”。 1.2.启用IIS功能 打开“控制面板” > “程序和功能” > “启用或关闭 Windows 功能”。 勾选“Internet Information Services”&#xff0c;然后点击“确定…

《21天学通C++》(第十一章)多态

为什么需要多态&#xff1f; 为了最大限度地减少代码&#xff0c;提高可读性 1.虚函数 虚函数是C中的一种特殊成员函数&#xff0c;它允许在派生类&#xff08;也称为子类&#xff09;中重写&#xff08;覆盖&#xff09;基类的实现&#xff0c;使用virtual进行声明 在C中&am…