2

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

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

变量“de”是 struct dirent* 类型,正在检查它的类型,我收到错误:“struct dirent”没有名为“de_type”的成员

这就是我真正感到困惑和困惑的地方:我已经在 Windows(使用 dev C++)和 Ubuntu(使用 gcc)上编译了这段代码。我在两个操作系统上都收到了相同的错误,当我检查使用的库时,我相信这是普通的 gnu C 库,那里有一个名为 d_type 的变量:

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

我发现了对 dirent.h 文件的其他引用,这不是因为一个文件在不同的库中,如果是这种情况,我该如何加载该库以便编译代码?

对不起,很长的帖子,非常感谢所有回答的人!

4

1 回答 1

7

来自man readdir(3)

POSIX.1 要求的唯一结构中的字段是: d_name[],未指定大小,在终止空字节之前最多有 NAME_MAX 个字符;和(作为 XSI 扩展)d_ino。其他字段是非标准化的,并不存在于所有系统上;有关更多详细信息,请参见下面的注释。

然后继续

在 POSIX.1-2001 中仅指定了字段 d_name 和 d_ino。其余字段在许多但不是所有系统上都可用。在 glibc 下,程序可以通过测试是否定义了宏 _DIRENT_HAVE_D_NAMLEN、_DIRENT_HAVE_D_RECLEN、_DIRENT_HAVE_D_OFF 或 _DIRENT_HAVE_D_TYPE 来检查 POSIX.1 中未定义的字段的可用性。

除了 Linux,d_type 字段主要只在 BSD 系统上可用。如果进一步的操作取决于文件的类型,则此字段可以避免调用 lstat(2) 的费用。如果定义了 _BSD_SOURCE 功能测试宏,则 glibc 为 d_type 中返回的值定义以下宏常量:

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


附录:见下面@R.. 的评论和这个答案。总之:

  1. 使用正确的东西。添加-D_FILE_OFFSET_BITS=64到您的编译器标志并使用 64 位文件偏移进行构建。
  2. 检查你是否有d_type预处理器宏_DIRENT_HAVE_D_TYPE。如果是这样,请使用d_type. 从目录表(如果可用)中获取您想要的信息将比寻找和读取文件的所有 inode 更有效。
  3. 作为一种后备措施,(如上所述)用于stat读取 inode 并st_mode使用S_ISDIR()宏检查(或类似检查)。
于 2016-02-05T02:19:34.607 回答