fseek 函数和 lseek 系统调用一样。它也可以设置流(stream)中的位置,如流中下次读和写的位置。其中 offset 和 whence 参数的意思和值和 lseek 一样。然而, lseek 返回一个 off_t,而 fseek 返回一个整数: 0表示成功;-1表示失败;错误号 error 表示错误的类型。
用法:
[C++] 纯文本查看 复制代码 #include <stdio.h>
int fseek(FILE *stream, long int offset, int whence);
注意,当 fseek() 成功返回的时候,即使定位已经超出了文本的最大长度也是正确的,这时 fseek 会清除掉 EOF 标志(该标志一般为 -1)。看下面示例代码:
[C++] 纯文本查看 复制代码 #include <stdio.h>
int main(void)
{
FILE *fp;
int i;
int c;
fp = fopen("test.txt", "r");
for (i = 0; i < 3; i++)
fgetc(fp);
if (!fseek(fp, 3, SEEK_CUR)) {
for (i = 0; i < 10; i++) {
if ((unsigned char)(c = fgetc(fp)) != '\0')
printf ("%c\n", (unsigned char)c);
else
printf ("ok, got 'NULL' character\n");
}
}
else
printf ("fseek error\n");
fclose(fp);
return (0);
}
对于代码中所读文本,这里 “hello fseek" 这句话 echo 进去,然后运行输出此段程序:beyes@debian:~/C/libcall/fseek$ ./fseek
f
s
e
e
k
�
�
�
� 在上面输出中,k 和第一个乱码符之间有 2 个空格,其中一个空格是 printf() 中指定的 '\n' ,另外的一个空格是 test.txt 这个文本中自带的 '\n' -- echo 一条字符串进一个文本里,它会自动在文本末尾添加一个换行符,即 LF (LINE FEED,十六进制为 0xa,也就是 '\n' )。后面的 4 个问号就是 -1 ,也就是原来用来表示 EOF 的标志。
需要注意的是,所谓的 "fseek() 清除掉 EOF“ 标志并不是说,它将 -1 清除掉了(比如把 -1 变成了 0 或者别的什么数字),实质上,是 fseek() 自己遇到 EOF 时,它对它的无视罢了。对于这一点,可以通过在程序中添加 feof() 函数来验证,当 feof() 函数遇到 -1 时,它仍然认为是 EOF ,并达到了文件的末尾。如将中间的一段代码改为:
[C++] 纯文本查看 复制代码
if (!fseek(fp, 3, SEEK_CUR)) {
for (i = 0; i < 10; i++) {
if ((unsigned char)(c = fgetc(fp)) != '\0')
printf ("%c\n", (unsigned char)c);
else
printf ("ok, got 'NULL' character\n");
if (feof(fp)) {
printf ("encounter EOF and i = %d\n", i);
fclose(fp);
exit (0);
}
}
}
运行输出:beyes@debian:~/C/libcall/fseek$ ./fseek
h
e
l
f
s
e
e
k
�
encounter EOF and i = 6 由上面的输出得以验证。 |