如何使用c在Linux中查找目录?

时间:2013-05-02 17:38:42

标签: c linux

我正在linux中创建一个c程序,用户可以输入要找到的目录名。一世 以下是我编写的代码,但没有得到正确的输出。我正在搜索所有目录,直到找到目录 我只是个初学者。

#include<unistd.h>
#include<dirent.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/stat.h>
#include<errno.h>

void findDir(char *dir, char *name)
{
    DIR *dp;
    struct dirent *entry;
    struct stat statbuf;

    if((dp = opendir(dir)) == NULL)
    {
        printf("\ncan not open directory: %s", name);
        printf("\nDescription: %s", strerror(errno));
        return;
    }

    chdir(dir);

    while(( entry = readdir(dp)) != NULL)
    {
        lstat( entry->d_name, &statbuf);
        if(S_ISDIR( statbuf.st_mode))
        {
            if( strcmp(name,entry->d_name) == 0)
            {
                printf("Dir found");
                return;
            }
            findDir(entry->d_name, name);
        }
    }
    chdir("..");
    closedir(dp);
}

void main(int argc, char *argv[])
{
    if( argc != 2 )
    {
        printf("Error");
    }
    else
    {
        findDir("/home", argv[1]);
    }
}

请帮助!! 我在给出文档作为参数的同时获得了以下输出。实际上程序是无限的,我重复得到以下输出。这只是输出的一小部分。

  

无法打开目录:文件
  描述:打开文件太多
  无法打开目录:文件
  描述:打开文件太多
  无法打开目录:文件
  描述:打开太多   找到filesDir

4 个答案:

答案 0 :(得分:5)

问题是readdir() 重入。它依赖于一个内部缓冲区,当你递归时,它会被覆盖。如果您使用的是POSIX标准,则可以尝试重新进入的readdir_r

或者,您可以在开始递归之前将目录读入列表,然后一次处理列表中的项目。这样你就可以在尝试潜入目录树中的下一级别之前阅读整个目录,并且当前级别的条目不会丢失到更深层次的覆盖。

答案 1 :(得分:2)

您将遇到的另一个问题(以及可能现在最影响您的问题)是特殊目录条目...将显示在{的结果中{1}} / opendir()。您将需要使用以下内容检查并跳过这两个:

readdir()

答案 2 :(得分:0)

我快速浏览了一下。这是一些建议。

  • 调试时,可以在调试器中单步执行,也可以至少放一些print语句来查看实际发生的情况。我在遍历目录的循环中放入printf(),并发现它正在尝试访问..目录,因此它会离开/home并永远循环。

  • 因此,在循环中,在执行任何其他操作之前,请测试entry->d_name"."还是"..",如果是,请跳过该目录条目(您可以使用continue关键字。

  • 确保在函数返回之前调用closedir(dp);。例如,当您的代码打印消息can not open directory:时,您的函数将返回而不关闭目录。顺便说一下,您应该在该错误消息中打印entry->d_name,而不是name

错误Too many open files是因为你的循环跟随..所以它永远不会停止,并且它找到了大量无法打开的目录,因此错误退出时代码不会调用closedir()意味着越来越多的目录被打开。

  • 您的程序将在找到目标目录后继续运行!它将打印一条消息,但继续前进。您可以修改函数findDir()以返回代码,说明它是否找到目标,并在此情况下停止程序。

答案 3 :(得分:0)

您最好使用nftw(3)库函数,它可以通过文件树递归遍历。

如果您不被允许使用它,您至少可以研究它的来源,例如:来自MUSL libc文件src/misc/nftw.c,我发现它非常易读。

顺便说一句,您对lstat的调用在您的代码中是错误的,您需要构建整个文件路径。

您需要在程序中使用gdb调试器。您可能还希望使用strace来了解它正在执行哪些系统调用(而strace - 某些find命令也会教您很多事情。)