struct dirent在头文件中没有de_type

Jus*_*irt 1 c gnu dirent.h libraries

所以我有一个项目,我需要构建一个小的简单文本shell,可以运行,编辑和读取目录中的文件.我有一个应该工作的小原型,除了我编译时,我收到一个错误,关于在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);
}
Run Code Online (Sandbox Code Playgroud)

变量"de"的类型为struct dirent*,并且正在检查它的类型,我得到错误:'struct dirent'没有名为'de_type'的成员

这里我真的很困惑和困惑:我在两个窗口(使用开发C++)和Ubuntu(使用gcc)上编译了这段代码.我在两个操作系统上都收到了相同的错误,当我检查使用的库时,我相信这是正常的gnu C库,有一个名为d_type的变量:

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

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

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

e0k*_*e0k 6

来自man readdir(3):

由POSIX.1强制要求的dirent结构中的唯一字段是: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()宏(或类似的检查).

  • 使用 `stat` 会慢一个数量级或更糟,因为这样的代码的运行时间大致与系统调用的数量成正比,而 `stat` 是一个相当繁重的系统调用。那是在您甚至没有解决 IO 负担之前:通过使用 `stat`,您可以在每个目录条目的 inode 上执行 IO(大量随机访问),而不仅仅是读取目录表(紧凑线性读取)。如果没有定义 `_DIRENT_HAVE_D_TYPE`,你应该提供一个可移植的回退到 `stat`,否则 **如果你有的话 **肯定使用 `d_type`**。 (2认同)