C:SEEK_END在printf中显示意外值

时间:2017-05-05 17:21:02

标签: c

当我使用SEEK_END时,我希望它对应于流中最后一个字符的位置。但是在printf里面,它似乎没有。

我有一个包含1010个字符的文件。我用fopen打开它,然后我尝试打印这个文件的最后一个字符的位置:

printf("Last position is: %d\n", SEEK_END);

输出为Last position is: 2,而我预计它为Last position is: 10102与最后一行或最后一列不对应,因为我有101行,每行10个字符。我不知道它是什么。

奇怪的是,这段代码效果很好:

fseek(file, 0, SEEK_END);
printf("Last position is: %d\n", ftell(file));

输出为Last position is: 1010。但问题是我在文件中移动虚拟光标,这是我不想要的。

如何在不更改虚拟光标位置的情况下打印SEEK_END的值,更重要的是,为什么printf输出2

3 个答案:

答案 0 :(得分:5)

你有一个误解。 SEEK_END不是一个神奇的符号,它以某种方式存储您正在考虑的文件的长度。它是一个常量,用作告诉fseek()用于指定文件偏移量的参考点的代码。

如果要确定您知道其名称的文件的大小,并且您在POSIX系统上,则可以使用fstat()。如果您拥有的只是FILE *,那么您最好的选择可能是记录当前位置,寻找流的末尾,确定位置,然后回到起点:

fpos_t current;
long end;

/* error checks omitted for brevity */
fgetpos(file, &current);
fseek(file, 0, SEEK_END);
end = ftell(file);
fsetpos(file, &current);

printf("Last position is: %ld\n", end);

当然,所有这些都取决于可以搜索的流。并非所有人都是。如果你有一个不可寻找的流,那么很可能没有意义上的最后位置。

文件偏移超过long的大小也存在潜在问题。可以预期fgetpos()fsetpos()对此不敏感,但其伴随的fpos_t类型可能是聚合类型(即结构),因此不是直接可询问的。您可以使用lseek()解决这个问题,但这来自POSIX,而非标准C。

答案 1 :(得分:3)

SEEK_ENDfseek的参数,它告诉fseek函数它应该如何定位在文件中。您看到2可能是因为在stdio.h中它显示#define SEEK_END 2,但实际值未指定。

要获得偏移,您需要使用ftell()

您可以查看fseek here的具体实现。

答案 2 :(得分:1)

here可以看出SEEK_END是一个整数常量。它不像保存文件最后位置的变量。因此,每当您打印SEEK_END值时,它将为2。