文件操作(2)【文件的随机读写】【文件读取结束的判定】

一.文件的随机读写

1.fseek函数

这个函数可以根据文件指针的位置和偏移量来定位文件指针(文件内容的光标)。有三个参数:

  • stream:文件指针,指向要设置位置的文件。
  • offset:偏移量,可以为正数、负数或0。正数表示向文件末尾偏移,负数表示向文件开头偏移,0表示从文件开头偏移。
  • origin:起始位置,可以取下面的值:
    • SEEK_SET:从文件开头开始偏移。
    • SEEK_CUR:从当前位置开始偏移。
    • SEEK_END:从文件末尾开始偏移。
#include<stdio.h>
int main()
{
	FILE* pf = fopen("text.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//fputs("abcdefghi", pf);
	int ch = fgetc(pf);
	printf("%c\n", ch);

	fseek(pf, 4, SEEK_CUR);//f

	ch = fgetc(pf);
	printf("%c", ch);

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

当我把第一个字符a给读取出来后,光标就移动到了b的位置,但是我这里使用了fseek,SEEK_CUR是从当前位置开始,偏移量为4,直接走到了f这里。如果是用另外两中的话,只需要改变偏移量就可以随便读取我们想要的地方。

2.ftell函数

这个函数可以返回相对于起始位置的偏移量。

还是用上面的代码

#include<stdio.h>
int main()
{
	FILE* pf = fopen("text.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//fputs("abcdefghi", pf);
	int ch = fgetc(pf);//a

	fseek(pf, 4, SEEK_CUR);//f
	printf("%d", ftell(pf));

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

打印出来的就是5。

因为此时光标的位置在f的位置。

3.rewind函数

这个函数可以让文件指针的位置回到文件的起始位置。

还是上面的代码。

#include<stdio.h>
int main()
{
	FILE* pf = fopen("text.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//fputs("abcdefghi", pf);
	int ch = fgetc(pf);//a

	fseek(pf, 4, SEEK_CUR);//f

	rewind(pf);//回到起始位置

	ch = fgetc(pf);
	printf("%c", ch);
	fclose(pf);
	pf = NULL;
	return 0;
}

打印出来的就还是a

二.文件读取结束的判定

feof函数和ferror函数

关于这个函数其实被许多人都给用错了,在文件读取的过程中不能用feof的返回值判断文件是否结束。

它的作用是:当文件读取结束后,判断读取结束的原因是否是:遇到文件末尾结束。

也就是说,文件现在读取结束了,但是是什么原因结束的呢?1.遇到文件末尾——feof。2.读取时发生了错误——ferror。

当我们打开一个流的时候,这流上有两个标记值:1.是否遇到文件末尾。2.是否发生错误了。假如在读取的过程中真的遇到了这两种情况,就会把这两个标记给设置一下。而feof是检测是否遇到文件末尾的,ferror则是检测是否发生了错误。

比如fgetc函数在读取到文件末尾或者遇到错误会返回EOF。fgets函数在读取到文件末尾或者错误的时候会返回NULL。但是我们怎么知道是哪一种情况,导致它们返回了这样的值呢?

它返回非零值(通常为1)表示有错误发生,返回0表示没有错误发生。

当文件指针指向的文件已经到达文件末尾时,feof函数返回非零值;否则,返回零。

#include<stdio.h>
int main()
{
	FILE* pf = fopen("text.txt", "r");
	if (pf == NULL)//文本里面是abcdefghi
	{
		perror("fopen");
		return 1;
	}
	int ch = 0;
	while ((ch = fgetc(pf)) != EOF)
	{
		printf("%c\n", ch);
	}
	if (feof(pf))
	{
		printf("遇到文件末尾,正常结束");
	}
	else if (ferror(pf))
	{
		perror("fgetc");
	}
	fclose(pf);
	pf = NULL;
	return 0;
}

这里是正常结束,当然还有错误的情况。

#include<stdio.h>
int main()
{
	FILE* pf = fopen("text.txt", "r");
	if (pf == NULL)//文本里面是abcdefghi
	{
		perror("fopen");
		return 1;
	}
	//int ch = 0;
	//while ((ch = fgetc(pf)) != EOF)
	//{
	//	printf("%c\n", ch);
	//}
	char c = 0;
	for (c = 'a'; c <= 'z'; c++)
	{
		fputc(c,pf);
	}
	if (feof(pf))
	{
		printf("遇到文件末尾,正常结束");
	}
	else if (ferror(pf))
	{
		perror("fgetc");
	}
	fclose(pf);
	pf = NULL;
	return 0;
}

这里我是用"r"来读取文件,但是我用了fputc函数,非要往文件里面写肯定是错误的了。

三.文件缓存区

ANSIC标准采用“缓冲文件系统”处理数据文件,所谓缓冲文件系统是指系统系统自动的在内存中为程序中每一个正在使用的文件开辟一块文件缓冲区,从内存向磁盘输出数据会先送到文件缓冲区,等装满缓冲区的时候再一起送到磁盘里面去,如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个的将数据送到程序数据区(程序变量等)。

到这里差不多文件操作都差不多结束了。感谢大家的观看,如有错误,还请大家多多指正。

  • 21
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值