【问题标题】:List files in directories using Glob() in C在 C 中使用 Glob() 列出目录中的文件
【发布时间】:2016-10-05 02:19:01
【问题描述】:

基本上,到目前为止我有这个代码:

#include <glob.h>
#include <string.h>
#include <stdio.h>

# define ERROR 1
# define FAILURE -1

int main(int ac, char **av)
{
  glob_t globlist;
  int i;

  i = 0;               
  if (ac == 1)
    return (-1);
  else
    {
      if (glob(av[1], GLOB_PERIOD, NULL, &globlist) == GLOB_NOSPACE
          || glob(av[1], GLOB_PERIOD, NULL, &globlist) == GLOB_NOMATCH)
        return (FAILURE);
      if (glob(av[1], GLOB_PERIOD, NULL, &globlist) == GLOB_ABORTED)
        return (ERROR);
      while (globlist.gl_pathv[i])
        {
          printf("%s\n", globlist.gl_pathv[i]);
          i++;
        }
    }
  return (0);
}

例如,当我键入./a.out "*" 时,它会打印我所在的所有文件以及目录,但不会打印目录中的内容。我应该如何打印所有文件,包括子文件/文件夹?

谢谢

【问题讨论】:

  • 与您的问题完全无关,但您不应从main 函数返回-1。在“成功”时返回 0,在“失败”时返回小于 256 的 值。这是因为在 POSIX 系统(包括 Linux、OSX 和所有现代 Unix 系统)上,高位具有特殊含义。
  • 您可能想看看dirent.h 中的原型函数。
  • @alk 我知道 dirent.h,但我真的不知道如何很好地使用它。就像我认为我必须做递归一样,我错了吗?
  • 是的,你必须递归。因此,您需要将 glob 代码放入函数中(而不是 main())。也同意关于return() 的建议。祝你好运。
  • @shellter 谢谢!基本上我是第一次 glob,然后访问所有目录,然后再 glob 一次?

标签: c linux unix path glob


【解决方案1】:

如果您想检查整个树而不是一个特定的路径和文件名模式,请使用 nftw() 而不是 glob()

(通过使用 opendir()/readdir()/closedir() 来重新发明轮子绝对是愚蠢的,特别是因为 nftw() 应该优雅地处理文件系统更改,而自旋转树遍历代码通常会忽略所有困难的东西,只有在你自己的机器上的最佳条件下才能工作,在其他地方以惊人而美妙的方式失败。)

在过滤器函数中,使用fnmatch() 来决定文件名是否可以使用glob 模式。

如果您希望使用正则表达式进行过滤,请在调用 nftw() 之前使用 regcomp() 编译模式,然后在您的过滤器函数中使用 regexec()。 (正则表达式比 glob 模式更强大,并且它们被编译成一个紧密的状态机,所以它们也非常高效。)

如果您不确定两者之间的区别,glob patternsregular expressions 上的维基百科文章非常有用且内容丰富。

以上所有内容均在 POSIX.1-2008 中定义,因此它们可在所有 POSIX-y 操作系统中移植。

【讨论】:

  • 非常感谢您提供所有这些信息。不幸的是,我不能使用 nftw,因为它是用于学校项目的,并且此功能未经授权。
  • @iNukeLaPeste:在这种情况下,也许您应该考虑对所有命令行参数进行循环,而不是只使用第一个参数av[1]?这样,您可以提供多个 glob 模式,例如 '*' '*/*' '*/*/*',以查看最多三个目录深度的文件。递归扫描目录很容易出错,真的,真的,应该小心。
  • 我最喜欢的一个trippers-uppers 正在另一个窗口中运行new="dirname"; i=1; while true; do old="$new"; new="dirname$i"; i=$[i+1]; mv "$old" "$new" ; done,在您递归检查的树中。 (它将最初命名为dirname 的目录重命名为dirname1,并且数量每次都增加,尽可能频繁。这是一种压力测试。)正确编写的树递归并不介意,尽管它可能会错过从该更改名称目录开始的子树。写得不好的实现会让人感到困惑和重复,或者崩溃。
  • 即使是更恶劣的压力测试也很容易设计。特别是,在同一个目录中重命名是对文件系统的“轻量级”操作,但在目录之间移动需要更多的工作——并且更有可能混淆或崩溃写得不好的树扫描器。您可能会认为这是矫枉过正或罕见,但事实并非如此!例如,日志文件是“轮换”的,这通常包括三重重命名(或移动)。与在 emacs/vi/nano/gedit/etc 中编辑文件相同。或者,您可以在程序运行时使用桌面环境移动文件夹。 这样的事情确实会发生。
猜你喜欢
  • 2010-10-04
  • 2020-02-27
  • 1970-01-01
  • 2020-01-29
  • 1970-01-01
  • 2016-03-27
  • 1970-01-01
  • 2013-12-25
  • 2021-05-28
相关资源
最近更新 更多