C:printf中的SEEK_END显示意外值

C:printf中的SEEK_END显示意外值,c,C,当我使用SEEK\u END时,我希望它对应于流中最后一个字符的位置。但在printf中,它似乎不是 我有一个包含1010个字符的文件。我用fopen打开它,然后尝试打印此文件最后一个字符的位置: printf("Last position is: %d\n", SEEK_END); 输出是最后位置是:2,而我希望它是最后位置是:10102与最后一行或最后一列不对应,因为我有101行,每行10个字符。我不知道是什么 奇怪的是,该代码运行良好: fseek(file, 0, SEEK_END);

当我使用
SEEK\u END
时,我希望它对应于流中最后一个字符的位置。但在printf中,它似乎不是

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

printf("Last position is: %d\n", SEEK_END);
输出是
最后位置是:2
,而我希望它是
最后位置是:1010
2
与最后一行或最后一列不对应,因为我有101行,每行10个字符。我不知道是什么

奇怪的是,该代码运行良好:

fseek(file, 0, SEEK_END);
printf("Last position is: %d\n", ftell(file));
输出为
最后位置为:1010
。但这里的问题是,我正在移动文件中的虚拟光标,这是我不想要的


如何打印
SEEK\u END
的值而不必更改虚拟光标的位置,更重要的是,为什么我的
printf
输出
2

SEEK\u END
fseek
的一个参数,它告诉
fseek
函数它应该如何在文件中定位。您看到2可能是因为在
stdio.h
中它说
#define SEEK_END 2
,尽管实际值未指定

为了获得偏移量,需要使用
ftell()


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

从中可以看到SEEK\u END是一个整数常量。它不像保存文件最后位置的变量。因此,无论何时打印SEEK_结束值,它都将是2。

您有一个误解
SEEK\u END
并不是一个神奇的符号,它以某种方式存储了您现在想到的文件的长度。它是一个常量,用作告诉指定文件偏移量使用的参考点的代码

如果您想确定一个文件的大小,您知道该文件的名称,并且您在POSIX系统上,那么您可以使用
fstat()
。如果您只有一个
文件*
,那么您的最佳选择可能是记录当前位置,搜索到流的末尾,确定位置,然后搜索回起点:

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\u t
类型可能是聚合类型(即结构),因此不可直接查询。您可以使用
lseek()
解决这个问题,但它来自POSIX,而不是标准C。

我将重新表述它。。。类似于SEEK_END的东西是一种操作类型,但不是position@EugeneSh.better像那样?@Jens-gotcha:)运行上面的代码。出现此错误:在需要整数的位置使用了聚合值。从这里得到答案@Nguaial,是的,我的代码的第一个版本有一个潜在的可移植性问题。这是因为
fpos\u t
不一定是算术类型。我已经更新了我的代码以避免这个问题,并添加了关于相关可移植性问题的注释。