【发布时间】:2013-08-14 02:51:38
【问题描述】:
我有一个程序可以打开一个文件并检查它的长度。
FILE* fd = fopen(argv[1], "rb");
fseek(fd, 0, SEEK_END);
size_t flen = ftell(fd);
if (flen == ((size_t)-1)) {
printf("%s is a directory.\n", argv[1]);
fclose(fd);
exit(1);
}
现在,至少在 Linux 下,fopen() 在打开目录时返回一个有效的文件描述符。这会导致查找操作返回 -1(或者,由于 size_t 是无符号的,0xFFFFFFFFFFFFFFFF=264-1 在 64 位系统上)。
不幸的是,上述代码中的条件 (flen == ((size_t)-1)) 没有捕捉到这种情况,flen == 0xFFFFFFFF 也没有(编辑:应该是 0xFFFFFFFFFFFFFFFF)。 printf()-以%x 或%d 为格式字符串的命令表明比较的两边应该具有相同的值。
为什么比较运算符的行为如此奇怪,即使双方都是同一类型(size_t)?我使用 gcc 4.8.1 作为编译器。
【问题讨论】:
-
你不是说
sizeof(size_t)-1吗? -
@ScottyBauer 不,他没有。
-
另外,
FILE fd应为FILE *fd。而ftell()不会返回size_t,而是long。并且 -1 不是 64 位上的0xFFFFFFFF(假设 2 的补码),而是0xFFFFFFFFFFFFFFFF。 -
@ScottyBauer Google“C 类型转换”。
-
你可以
open()一个目录(因此fopen()它),但这就是你可以用它做的所有事情。目的是允许您在文件描述符上使用fchdir()。要读取目录,您需要使用opendir()、readdir()等。要查找其大小,您可以使用fstat(fileno(fd))— 尽管使用名称fd代替文件描述符而不是文件描述符让我印象深刻作为烂命名(我会使用FILE *fp = fopen("file", "r"); int fd = fileno(fp);)。