文件随机访问
操作文件时,偶尔需要针对文件中的某一部分进行读写操作。例如,要截取某一首歌中的一小段做手机铃声,这时使用顺序读写文件的方式是行不通的。为此,C语言提供了随机读写文件的相关函数,实现对文件任意位置进行读写的操作,具体介绍如下:
1、rewind()函数
rewind()函数的作用是将文件位置指针指向文件开头,函数声明所示:
void rewind(FILE * stream);
上述函数声明中,void表示该函数无返回值,参数stream表示一个文件指针。
2、fseek()函数
fseek()函数的作用是将文件位置指针指向指定位置,函数声明如下所示:
int fseek(FILE * stream, long offset, int whence);
上述函数声明中,参数stream表示一个文件指针,参数offset表示根据参数whence移动读写位置的偏移量,其中,参数whence的值有三个,具体如下:
● SEEK_SET:对应的数字值为0,表示从文件开头进行偏移;
● SEEK_CUR:对应的数字值为1,相对于文件位置指针当前位置进行偏移;
● SEEK_END:对应的数字值为2,相对于文件末尾进行偏移。
fseek()函数调用成功返回0,调用失败返回-1。通常情况下,fseek()函数适用于二进制文件,因为文本文件要进行字符转换,计算位置时往往会发生混乱。
假设现在有一个hellow.txt文件,文件内容仅有“hello world”一行字符串,接下来通过一个案例演示对hellow.txt文件进行随机读写,如例1所示。
例1 fseekFile.c
1 #define _CRT_SECURE_NO_WARNINGS
2 #include <stdio.h>
3 int main()
4 {
5 FILE* fp;
6 char s[16] = {0};
7 fp = fopen("hellow.txt", "r");
8 fseek(fp, 7, SEEK_SET);
9 fread(s, 1, 15, fp);
10 fclose(fp);
11 printf("%s", s);
12 return 0;
13 }
例1运行结果如图1所示。
图1 例1运行结果
在例1中,第7行代码以只读取方式打开hellow.txt文件;第8行代码将hellow.txt文件位置指针从开头向后偏移7个单位;第9行代码调用fread()函数从当前位置读取15个字节大小的数据到字符数组s中;第10行代码调用fclose()函数关闭文件。从图1中可以看出,控制台输出的内容是“world”。
接下来打开“hellow.txt”文件来验证读取的内容是否正确,文件内容如图2所示。
图2 hellow.txt文件内容
从图11-22中可以看出,文件位置指针从开头向后偏移7个单位,指向了字符‘w’,从字符‘w’处读取15个字符,则会读取后面的“world”字符串,到达文件末尾,读取结束。这与程序输出结果一致,说明随机读取文件内容的操作成功了。
3、ftell()函数
ftell()函数用于获取文件位置指针的当前位置,函数声明如下所示:
long ftell(FILE * stream);
上述函数声明中,参数stream表示文件指针。ftell()函数调用成功后,返回文件位置指针的当前位置,但如果当文件不存在或发生其他错误时,则函数的返回值为-1L。
接下来通过一个案例演示如何使用ftell()函数获取文件位置指针的当前位置,如例2所示。
例2 ftellFile.c
1 #define _CRT_SECURE_NO_WARNINGS
2 #include <stdio.h>
3 int main()
4 {
5 FILE * fp;
6 // 只读方式打开文件,文件必须存在
7 fp = fopen("hellow.txt", "r");
8 fseek(fp, 5, SEEK_SET); // 将文件位置指针从头开始偏移5位
9 printf("offset = %d\n", ftell(fp)); // 打印文件位置指针的当前位置
10 rewind(fp); // 将文件位置指针指向文件开头
11 printf("offset = %d\n", ftell(fp));
12 fseek(fp, 11, SEEK_CUR); // 将文件位置指针从当前位置开始偏移11位
13 printf("offset = %d\n", ftell(fp));
14 fclose(fp);
15 return 0;
16 }
例2运行结果如图3所示。
图3 例2运行结果
在例2中,第8行和第12行代码分别调用fseek()函数实现了文件位置指针的移动,第10行代码调用rewind()函数将文件位置指针移动到文件开头,第9行、第11行、第13行代码通过printf()函数格式化输出每次的文件位置指针的偏移量。从图3中可以看出,控制台成功打印出了文件位置指针的偏移量。