纯C:用的fopen打开一个目录() [英] plain C: opening a directory with fopen()

查看:1498
本文介绍了纯C:用的fopen打开一个目录()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我打开一个文件,并检查其长度的节目。

I have a program which opens a file and checks its length.

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 是无符号,为0xFFFFFFFF 64位系统上)。

Now, at least under Linux, fopen() returns a valid file descriptor when opening a directory. This results in the seek operation returning -1 (or, as size_t is unsigned, 0xFFFFFFFF on a 64-bit system).

不幸的是,在上述code的条件下( FLEN ==((为size_t)-1))没有赶上这种情况下,同样没有 FLEN == 0xFFFFFFFF的的printf() - 命令与%X ORD %d个作为格式字符串表明该比较的两侧应具有相同的值。

Unfortunately, the condition in the above code (flen == ((size_t)-1)) does not catch that case, neither does flen == 0xFFFFFFFF. printf()-Commands with %x ord %d as format string show that both sides of the comparison should have the same value.

为什么用这种奇怪的方式比较循规蹈矩运营商,即使双方是同一类型的(为size_t )?我使用GCC 4.8.1编译器为

Why does the comparison operator behave in such a strange way, even when both sides are of the same type (size_t)? I am using gcc 4.8.1 as compiler.

推荐答案

目录不会出现在C99标准(或C2011的)存在。因此,通过定义,的fopen -ing一个目录或者是具体执行或不确定的行为。

Directories do not exist in the C99 standard (or the C2011 one). So by definition, fopen-ing a directory is either implementation specific or undefined behavior.

的fopen(3)可能失败(给人一种 NULL 结果)。 fseek的(3)也会失败(通过返回-1) 。然后你应该preferably检查错误号(3)或使用 PERROR(3)

fopen(3) can fail (giving a NULL result). fseek(3) can also fail (by returning -1). And then you should preferably check errno(3) or use perror(3)

FTELL 是记录返回 -1L 失败。在64位的Linux,这是 0xffffffffffffffff

ftell is documented to return a long, and -1L on failure. On 64 bits Linux this is 0xffffffffffffffff.

您code应该代替

FILE* fd = fopen(argv[1], "rb");
if (!fd) 
  { perror(argv[1]); exit(EXIT_FAILURE); };
if (fseek(fd, 0, SEEK_END)<0) 
  { perror("fseek"); exit(EXIT_FAILURE); };
long flen = ftell(fd);
if (flen == -1L)
  { perror("ftell"); exit(EXIT_FAILURE); };

BTW,在Linux / Debian的/ SID /带的libc-2.17和3.10.6内核AMD64,即codeS运行正常时,的argv [1] / tmp目录;惊喜地 FLEN LONG_MAX 0x7fffffffffffffff

BTW, On Linux/Debian/Sid/AMD64 with libc-2.17 and 3.10.6 kernel, that codes runs ok when argv[1] is /tmp; surprizingly, flen is LONG_MAX i.e. 0x7fffffffffffffff

这篇关于纯C:用的fopen打开一个目录()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆