2016-02-05 801 views
1

所以我有一个项目,我需要构建一个小的简单文本shell,可以运行,编辑和读取目录中的文件。我有一个小的原型应该可以工作,除了编译时,我收到了有关在dirent.h头文件中使用的struct dirent中找不到d_type的错误。struct dirent在头文件中没有de_type

d = opendir("."); 
c = 0; 
while ((de = readdir(d))){ 
    if ((de->de_type) & DT_DIR) 
    printf(" (%d Directory: %s) \n", c++, de->de_name); 
} 

变量“德”是类型结构的dirent *,并正在检查它的类型,我得到的错误:“结构的dirent”没有名为“de_type”

这里成员就是我真的难倒和困惑:我已经在两个窗口(使用dev C++)和Ubuntu(使用gcc)上编译了这段代码。我收到两个操作系统的相同的错误,当我检查使用的库,这是正常的GNU C库,我相信,有一个变量有名为d_type:

https://www.gnu.org/software/libc/manual/html_node/Directory-Entries.html

我发现了其他的引用到一个dirent.h文件,这并不是因为一个库位于不同的库中,并且如果是这样的话,我如何加载该库以便编译代码?

对不起,很长的文章,非常感谢所有谁回答!

+0

您使用的是什么文件系统类型? – e0k

+0

好的,所以现在这个问题根本没有意义,因为标题中说'd_type'和其他地方都有'de_type'。 – user3386109

回答

5

man readdir(3)

The only fields in the dirent structure that are mandated by POSIX.1 are: d_name[], of unspecified size, with at most NAME_MAX characters preceding the terminating null byte; and (as an XSI extension) d_ino. The other fields are unstandardized, and not present on all systems; see NOTES below for some further details.

然后继续

Only the fields d_name and d_ino are specified in POSIX.1-2001. The remaining fields are available on many, but not all systems. Under glibc, programs can check for the availability of the fields not defined in POSIX.1 by testing whether the macros _DIRENT_HAVE_D_NAMLEN, _DIRENT_HAVE_D_RECLEN, _DIRENT_HAVE_D_OFF, or _DIRENT_HAVE_D_TYPE are defined.

Other than Linux, the d_type field is available mainly only on BSD systems. This field makes it possible to avoid the expense of calling lstat(2) if further actions depend on the type of the file. If the _BSD_SOURCE feature test macro is defined, then glibc defines the following macro constants for the value returned in d_type:

所以我建议只是继续使用stat()检查项的类型。 (或者lstat()不遵循符号链接。)struct stat包含字段st_mode,可以使用POSIX宏S_ISDIR(m)来检查它是否是目录。


附录:见@R ..的评论下方this answer。总结:

  1. 使用正确的东西。将-D_FILE_OFFSET_BITS=64添加到您的编译器标志并使用64位文件偏移进行构建。
  2. 检查您是否有d_type与预处理器宏_DIRENT_HAVE_D_TYPE。如果是这样,请使用d_type。从目录表中获取所需的信息(如果可用)将比寻求读取文件的所有inode的&更高效。
  3. 作为回退措施,(如上所述)使用stat来读取inode,并使用S_ISDIR()宏(或类似检查)检查st_mode
+1

你错过了一个细节 - 缺少OP'd_type'的原因是它在'dirent'的遗留32位''off_t'版本中缺失,你应该永远不会使用**。用'-D_FILE_OFFSET_BITS = 64'构建,一切都会好的。 –

+0

@R ..为了兼容性,最好是“统计”条目? – e0k

+1

使用'stat'的速度会慢一点或更低,因为这样的代码的运行时间大致与系统调用的数量成正比,'stat'是一个相当重的系统调用。这是在你承担IO负担之前:通过使用'stat',你可以在每个dir条目的inode上执行I​​O(重度随机访问),而不仅仅是读取目录表(紧凑线性读取)。如果'_DIRENT_HAVE_D_TYPE'没有被定义,你应该提供一个可移植的回退到'stat',否则**肯定使用'd_type' **如果你有它。 –