C语言中的文件操作(二)

本文为上篇文章的补充 C语言中的文件操作(一)


前言

前面我们已经初步学习了一些文件操作,今天来做一些补充。
在这里插入图片描述


一.文件的指定读写

我们通过改变pf指针的位置,可以实现指定位置的读写

1.fseek

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

stream 是指向 FILE 对象的指针,该FILE对象标识了流。
offset 是相对origin 的偏移量,以字节为单位。
origin是表示开始添加偏移 offset 的位置。它一般指定为下列常量之一:

SEEK_SET 文件的开头
SEEK_CUR 文件指针的当前位置
SEEK_END 文件的末尾

我们通过读一个字符串来加深理解。
先用fgets写入一个字符串

int main()
{
    
    
	//打开文件
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
    
    
		perror("fopen");
		return 1;
	}
	//我们先写入一个字符串
	fputs("A nice boy", pf);

	//关闭文件
	fclose(pf);
	pf = NULL;
}

用fgetc读取第一个字符,
在这里插入图片描述
注意到使用了SEEK_END
用fseek调整指针位置到文件末,并偏移-2个单位
代码如下:

int main()
{
    
    
	//打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
    
    
		perror("fopen");
		return 1;
	}
	//从头开始读
	int ch = fgetc(pf);
	printf("%c ", ch);
	//调整pf位置为文件末,并且偏移-2个单位
	fseek(pf, -2, SEEK_END);
	//再次读,并打印
	ch = fgetc(pf);
	printf("%c ", ch);
	//关闭文件
	fclose(pf);
	pf = NULL;
}

图解:
在这里插入图片描述
因此程序输出结果为A 和 o

2.ftell

long int ftell ( FILE * stream);

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

我们在上文的代码用添加一个语句printf(“%ld”, ftell(pf));
在这里插入图片描述

打印的结果恰好为9.


3.rewind

void rewind( FILE * stream);

用于将文件指针返回文件的起始位置。

int main()
{
    
    
	//打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
    
    
		perror("fopen");
		return 1;
	}
	//从头开始读一个字符
	int ch = fgetc(pf);
	//调整pf位置为文件末,并且偏移-2个单位
	fseek(pf, -2, SEEK_END);
	//使文件指针返回起始位置
	rewind(pf);
	//计算偏移量并打印
	printf("%ld",ftell(pf));
	//关闭文件
	fclose(pf);
	pf = NULL;
}

打印后发现偏移量为0,即回到了起始位置。
在这里插入图片描述

二.文本文件和二进制文件

1.文本文件:

这类文件以文本的ASCII码形式存储在计算机中。 它是以"行"为基本结构的一种信息组织和存储方式。

2.二进制文件:

这类文件以文本的二进制形式存储在计算机中,用户一般不能直接读懂它们,只有通过相应的软件才能将其显示出来。

在这里插入图片描述
简单来说,
我们能直接看得懂的就是文本文件,
看不懂的就是二进制文件。

三.文件读取结束的判定

1.文本文件是否结束

  • 使用fgetc判断返回值是否为EOF
  • 或者使用fgets判断返回值是否为NULL

示例:

int main()
{
    
    
	int c;
	FILE* pf = fopen("test.txt", "r");
	if (!pf)
	{
    
    
		perror("fopen");
		return 1;
	}
	//fgetc 当读取失败或者遇到文件结束的时候,返回EOF
	while ((c = fgetc(pf)) != EOF)
	{
    
    
		putchar(c);
	}
	if (ferror(pf))//判断是否为读写时出错
		puts("I/O error when reading");
	else if (feof(pf))//判断是否为文件结尾
		puts("End of file reached successfully");
}

2.二进制文件是否结束

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

四.文件缓冲区

  文件缓冲区是用以暂时存放读写期间的文件数据而在内存区预留的一定空间。
  由于CPU 与 I/O 设备间速度不匹配。为了缓和 CPU 与 I/O 设备之间速度不匹配矛盾。文件缓冲区是用以暂时存放读写期间的文件数据而在内存区预留的一定空间。使用文件缓冲区可减少读取硬盘的次数。
在这里插入图片描述
怎样理解呢?
比方说,我们在一些游戏里会用金币兑换道具。
假如一个金币兑换一个道具,可以批量兑换
我们就没有必要每获得一个游戏币就兑换一次,
可以攒到一定数量一次性全换了
这样就提高了效率。

在这里插入图片描述

VS2019缓冲区测试:

将字符串“abcdef”写入文件,
立刻打开文件,发现文件里没有内容
用fflush手动刷新缓冲区,再次打开文件,
文件里有了“abcdef”

#include<stdio.h>
#include<windows.h>
int main()
{
    
    
	//打开文件
	FILE* pf = fopen("test.txt", "w");
	//先把字符串放进缓冲区
	fputs("abcdef", pf);
	printf("睡眠十秒,已经写入数据,但是文件里没有内容\n");
	Sleep(10000);
	printf("刷新缓冲区\n");
	//刷新缓冲区,此时成功写入
	fflush(pf);
	printf("睡眠十秒,已经写入数据,文件里已经有内容了\n");
	Sleep(10000);
	//关闭文件
	fclose(pf);
	pf = NULL;
}

总结

以上就是今天要讲的内容啦。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/m0_63742310/article/details/124031828