验证码: 看不清楚,换一张 查询 注册会员,免验证
  • {{ basic.site_slogan }}
  • 打开微信扫一扫,
    您还可以在这里找到我们哟

    关注我们

C语言如何实现随机读写文件

阅读:624 来源:乙速云 作者:代码code

C语言如何实现随机读写文件

1.fseek

前面已经剧透过了,fseek可以改变记录读写位置的指针的指向,从而实现文件的随机读写。该函数的声明如下:

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

第一个参数大家都很熟悉了,就是一个文件指针,告诉fseek我现在操作的是哪个文件。

第二个参数,offset是偏移量的意思,大家先记住。第三个参数,origin,顾名思义,即“起始位置”。后面两个参数让人摸不着头脑,但是配合起来就很有意思了。

举个例子:假设一个文件中存有abcdefg,当你用fopen打开这个文件时,一个记录读写位置的指针就指向了起始位置,也就是指向了a。如果我想读取第5个字符,即e呢?那我就要让这个指针指向e,这样再fgetc就能读到e了。

我可以这样算:e相对于起始位置a,向右偏移了4个字符,因为相对于a,a自己的偏移量是0,b是1,c是2,d是3,e自然是4。那么,偏移量offset(fseek的第二个参数)就是4,这个4是相对于起始位置的,这个“相对于”哪里,也就是origin(fseek的第三个参数)的位置,此时origin就是“起始位置”,明白了吧。而fseek用一个宏SEEK_SET来表示“起始位置”,所以此时fseek的调用如下:

fseek(pf, 4, SEEK_SET);

下面我们来验证一下。先在工程目录下创建一个文件,文件名是test.txt,然后在里面输入abcdefg。

C语言如何实现随机读写文件

按照打开文件->读文件->关闭文件的顺序,写代码:

#include 

int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	fseek(pf, 4, SEEK_SET);
	putchar(fgetc(pf));

	fclose(pf);
	pf = NULL;

	return 0;
}

打开文件后,使用fseek让记录读写位置的指针指向e,接着用fgetc读取e并用putchar打印出来,输出结果如下:

C语言如何实现随机读写文件

我们就成功跳过了前面的abcd,直接读取到e,实现了文件的随机读写。

当然,读取到e不止有这一种写法。fseek的第三个参数origin有三种取值,分别是:

1.SEEK_SET,表示起始位置。

2.SEEK_CUR,表示当前指向的位置。

3.SEEK_END,表示文件末尾。

SEEK_SET和SEEK_CUR都很好理解,需要注意的是,SEEK_END不是指向最后一个字符,而是指向最后一个字符的下一个位置。比如,一个文件中存有abcdefg,SEEK_END不是指向g,而是指向g的下一个位置。所以同样是读到e,如果origin是SEEK_END,offset就应该是-3,因为g的偏移量是-1,f是-2,所以e是-3。把上面代码中的fseek的调用方式改一下,其他不变:

fseek(pf, -3, SEEK_END);

也可以读到e,因为在执行完上面这行代码后,记录读写位置的指针就指向了e,所以读取时就跳过了前面的abcd,直接读到e。说明一下,由于读写前该指针指向了e,调用fgetc读完e后,该指针就指向了e后面的f,也就是说,此时SEEK_CUR就指向了f,如果我们想读到b呢?可以数一下,abcdefg,b相对于SEEK_CUR(指向f)的偏移量就是-4,如果像下面的代码这样写:

#include 

int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	fseek(pf, -3, SEEK_END); // 指向e
	putchar(fgetc(pf)); // 读完e后指向f

	fseek(pf, -4, SEEK_CUR); // 指向b
	putchar(fgetc(pf)); // 读完b后指向c

	fclose(pf);
	pf = NULL;

	return 0;
}

输出结果如下:

C语言如何实现随机读写文件

2.ftell

我如果想知道此时记录读写位置的指针相对于起始位置的偏移量(即相对于SEEK_SET的偏移量)是多少,就可以问问ftell函数。该函数声明如下:

long int ftell ( FILE * stream );

ftell会返回当前相对于起始位置的偏移量。比如前面的例子中调用:

#include 

int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	fseek(pf, -3, SEEK_END); // 指向e
	putchar(fgetc(pf)); // 读完e后指向f

	fseek(pf, -4, SEEK_CUR); // 指向b
	putchar(fgetc(pf)); // 读完b后指向c

	printf("n%ldn", ftell(pf));

	fclose(pf);
	pf = NULL;

	return 0;
}

由于此时记录文件读写位置的指针指向了c,偏移量是2(a为0,b为1,c为2),所以会输出2。

C语言如何实现随机读写文件

3.rewind

rewind的作用是,让指向文件读写位置的指针指向文件的起始位置。该函数声明如下:

void rewind ( FILE * stream );

其实非常简单,rewind(pf);和fseek(pf, 0, SEEK_SET);是等价的。

在前面的例子中,记录文件读写位置的指针左右横跳,最后指向了c,此时ftell也返回了2,这时如果我rewind一下,该指针就又指向了起始位置,即a,再ftell就能知道偏移量回到了0,如果再fgetc,就能重新读取到a了。代码如下:

#include 

int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	fseek(pf, -3, SEEK_END); // 指向e
	putchar(fgetc(pf)); // 读完e后指向f

	fseek(pf, -4, SEEK_CUR); // 指向b
	putchar(fgetc(pf)); // 读完b后指向c

	printf("n%ldn", ftell(pf));

	rewind(pf);
	printf("%ldn", ftell(pf));
	putchar(fgetc(pf)); // a

	fclose(pf);
	pf = NULL;

	return 0;
}

输出结果:

C语言如何实现随机读写文件

当然,把上述代码中的rewind(pf);换成fseek(pf, 0, SEEK_SET);的效果是一样的。

分享到:
*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: hlamps#outlook.com (#换成@)。
相关文章
{{ v.title }}
{{ v.description||(cleanHtml(v.content)).substr(0,100)+'···' }}
你可能感兴趣
推荐阅读 更多>