这篇文章主要讲解了“C语言如何实现随机读写文件”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“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。
按照打开文件->读文件->关闭文件的顺序,写代码:
#include <stdio.h> 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打印出来,输出结果如下:
我们就成功跳过了前面的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 <stdio.h> 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; }
输出结果如下:
2.ftell
我如果想知道此时记录读写位置的指针相对于起始位置的偏移量(即相对于SEEK_SET的偏移量)是多少,就可以问问ftell函数。该函数声明如下:
long int ftell ( FILE * stream );
ftell会返回当前相对于起始位置的偏移量。比如前面的例子中调用:
#include <stdio.h> 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%ld\\n", ftell(pf)); fclose(pf); pf = NULL; return 0; }
由于此时记录文件读写位置的指针指向了c,偏移量是2(a为0,b为1,c为2),所以会输出2。
3.rewind
rewind的作用是,让指向文件读写位置的指针指向文件的起始位置。该函数声明如下:
void rewind ( FILE * stream );
其实非常简单,rewind(pf);和fseek(pf, 0, SEEK_SET);是等价的。
在前面的例子中,记录文件读写位置的指针左右横跳,最后指向了c,此时ftell也返回了2,这时如果我rewind一下,该指针就又指向了起始位置,即a,再ftell就能知道偏移量回到了0,如果再fgetc,就能重新读取到a了。代码如下:
#include <stdio.h> 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%ld\\n", ftell(pf)); rewind(pf); printf("%ld\\n", ftell(pf)); putchar(fgetc(pf)); // a fclose(pf); pf = NULL; return 0; }
输出结果:
当然,把上述代码中的rewind(pf);换成fseek(pf, 0, SEEK_SET);的效果是一样的。
感谢各位的阅读,以上就是“C语言如何实现随机读写文件”的内容了,经过本文的学习后,相信大家对C语言如何实现随机读写文件这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是云搜网,小编将为大家推送更多相关知识点的文章,欢迎关注!