【问题标题】:C use of dirent.hC使用dirent.h
【发布时间】:2018-03-15 06:59:48
【问题描述】:

最终更新- 答案在已接受答案的 cmets 中。

首先,我意识到这个问题还有很多其他答案。我已经经历了其中的大部分,这段代码是经历了许多其他答案的组合。我要做的就是找到目录中每个文件的完整路径。

#include <limits.h>
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
     DIR *d;
     struct dirent * dir;
     char fullpath[PATH_MAX + 1];
     d = opendir("/home/adirectory");
     if(d != NULL)
     {
          while((dir = readdir(d)) != NULL)
          {
               realpath(dir->d_name, fullpath);
               printf("[%s]\n", fullpath);
               printf("%s\n", dir->d_name);

          }
          // addition of the following line yields
          // Value too large for defined data type
          perror("Something isn't working: ");
          closedir(d);

     }

return 0;
}

更新#3:

失败的调用是dir = readdir(d),这就是为什么我有 perror 紧接在 while 循环之后。

更新#2:

这在 CentOS 和 Ubuntu gcc 4.8.5 + 上运行良好。不工作 Solaris gcc 4.5.2。

更新: 有错误提示:

值对于定义的数据类型来说太大了

...但我不确定是什么原因造成的。

这总是只打印我正在从中运行程序的当前工作目录。即便如此,它实际上并没有列出该目录中除了“。”之外的任何文件。和 ”..” 。是什么赋予了?是否存在某种许可问题?这个解决方案在 2017 年不起作用吗?

【问题讨论】:

  • 我按原样编译并运行了它,它对我来说很好用。您是否拥有/home/adirectory 的读取和执行权限?试试cd /home/adirectory 看看你能不能做ls 并得到结果。
  • 在 Linux 上对我来说没问题。我确实将目录更改为我的主目录。
  • 我不应该只需要读取权限吗?
  • 您没有显示对来自realpath() 的返回值的任何检查;它可能会失败,所以你应该检查会发生什么。
  • 看起来像 realpath 失败,测试返回值和 errnoENOMEMENAMETOOLONG

标签: c solaris cc


【解决方案1】:

d_name 字段包含文件在其遍历的目录上下文中的名称。所以,它不包含任何路径,只包含名称。

因此,为了让您使用它的路径,您需要将d_name 附加到目录的名称中,如下所示:

 char *myHomeDir = "/home/adirectory";
 d = opendir(myNomDir);
 . . .
 while((dir = readdir(d)) != NULL) {
    char filepath[PATH_MAX + 1] ;
    strcpy(filepath, myHomeDir);
    strcat(filepath, "/");
    strcat(filepath, dir->d_name);
    realpath(filepath, fullpath);

当然,为了清楚起见,上面的内容只是一个框架代码。它可以更好地优化,您应该使用strncpy 系列函数。

【讨论】:

  • 所以这让我找到了正确的路径,然后才打印到当前工作目录的路径。但是我仍然看到同样的问题。和 .. 被打印出来,对于定义的数据类型,我将错误消息值变大。
  • 是编译时消息还是运行时消息?如果是前者,那么它应该给你一个行号,如果是后者,它听起来像是一个 32/64 大小的共享库混合。您可以使用“-m32”或“-m64”限定符进行编译和链接吗?
  • 哇,看来-m64 解决了这个问题!谢谢!尽管如果您愿意详细说明,我仍然不明白究竟是什么问题?
  • @LBaelish 看起来就像您以 32 位模式编译并且运行时共享库​​是 64 位。系统加载程序在尝试将 lib 中的一些 64 位数据放入 32 位变量时阻塞。
  • @LBaelish 64 位 Linux 上的默认编译模式是 64 位。 Solaris 上的默认编译模式始终为 32 位,您必须明确选择 64 位模式。如果您的一个文件大于 2 GB,那么如果您编译 32 位,则在任一操作系统上都会出现该错误。在您的 Solaris 系统上,请参阅 man lf64man lfcompile
猜你喜欢
  • 2015-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-14
  • 1970-01-01
  • 2016-12-25
  • 2014-03-15
  • 1970-01-01
相关资源
最近更新 更多