当我使用SEEK_END
时,我希望它对应于流中最后一个字符的位置。但是在printf里面,它似乎没有。
我有一个包含1010个字符的文件。我用fopen
打开它,然后我尝试打印这个文件的最后一个字符的位置:
printf("Last position is: %d\n", SEEK_END);
输出为Last position is: 2
,而我预计它为Last position is: 1010
。 2
与最后一行或最后一列不对应,因为我有101行,每行10个字符。我不知道它是什么。
奇怪的是,这段代码效果很好:
fseek(file, 0, SEEK_END);
printf("Last position is: %d\n", ftell(file));
输出为Last position is: 1010
。但问题是我在文件中移动虚拟光标,这是我不想要的。
如何在不更改虚拟光标位置的情况下打印SEEK_END
的值,更重要的是,为什么printf
输出2
?
答案 0 :(得分:5)
你有一个误解。 SEEK_END
不是一个神奇的符号,它以某种方式存储您正在考虑的文件的长度。它是一个常量,用作告诉fseek()
用于指定文件偏移量的参考点的代码。
如果要确定您知道其名称的文件的大小,并且您在POSIX系统上,则可以使用fstat()
。如果您拥有的只是FILE *
,那么您最好的选择可能是记录当前位置,寻找流的末尾,确定位置,然后回到起点:
fpos_t current;
long end;
/* error checks omitted for brevity */
fgetpos(file, ¤t);
fseek(file, 0, SEEK_END);
end = ftell(file);
fsetpos(file, ¤t);
printf("Last position is: %ld\n", end);
当然,所有这些都取决于可以搜索的流。并非所有人都是。如果你有一个不可寻找的流,那么很可能没有意义上的最后位置。
文件偏移超过long
的大小也存在潜在问题。可以预期fgetpos()
和fsetpos()
对此不敏感,但其伴随的fpos_t
类型可能是聚合类型(即结构),因此不是直接可询问的。您可以使用lseek()
解决这个问题,但这来自POSIX,而非标准C。
答案 1 :(得分:3)
SEEK_END
是fseek
的参数,它告诉fseek
函数它应该如何定位在文件中。您看到2可能是因为在stdio.h
中它显示#define SEEK_END 2
,但实际值未指定。
要获得偏移,您需要使用ftell()
。
您可以查看fseek here的具体实现。
答案 2 :(得分:1)
从here可以看出SEEK_END是一个整数常量。它不像保存文件最后位置的变量。因此,每当您打印SEEK_END值时,它将为2。