2017-04-12 117 views
0

我试图递归搜索目录的文件和输出文件的目录,如果它匹配给定:递归搜索文件

static int *search(char *path, const char *request, int depth, bool verbose) 
{ 
    DIR *dir; 
    struct dirent *ent; 
    char *start_dir = strcmp(path, "/") == 0 ? "root" : path; 

    printf("\nStarting in '%s' directory..\n\n", start_dir); 

    if ((dir = opendir(path)) != NULL) 
    { 
     while ((ent = readdir(dir)) != NULL) 
     { 
      if (verbose == true) 
      { 
       printf("Searching directory %s for file %s\n", ent->d_name, request); 
      } 
      if (ent->d_type == DT_DIR) 
      { 
       if ((strlen(path) + strlen(ent->d_name) + 1) > PATH_MAX) 
       { 
        puts("Path to long, cannot continue.."); 
       } 
       else 
       { 
        if (ent->d_name == DT_DIR && strcmp(ent->d_name, ".") != 0 && 
          strcmp(ent->d_name, "..") != 0) 
        { 
         printf("%s\n", ent->d_name); 
        } 
       } 
      } 
     } 
    } 
    return 0; 
} 

这会工作,但它不会输出的文件或目录在目录里面。示例:

@ubuntu:~/bin/c/find-files$ ./utilis test/-V 
Initialized to search for file: 'test'.. 
Starting in 'root' directory.. 

Searching directory vmlinuz.old for file test 
Searching directory boot for file test 
Searching directory home for file test 
Searching directory libx32 for file test 
Searching directory lib32 for file test 
Searching directory lib64 for file test 
Searching directory initrd.img for file test 
Searching directory srv for file test 
Searching directory usr for file test 
Searching directory . for file test 
Searching directory cdrom for file test 
Searching directory tmp for file test 
Searching directory initrd.img.old for file test 
Searching directory bin for file test 
Searching directory .. for file test 
Searching directory proc for file test 
Searching directory lib for file test 
Searching directory var for file test 
Searching directory dev for file test 
Searching directory sys for file test 
Searching directory media for file test 
Searching directory root for file test 
Searching directory snap for file test 
Searching directory run for file test 
Searching directory sbin for file test 
Searching directory opt for file test 
Searching directory lost+found for file test 
Searching directory mnt for file test 
Searching directory vmlinuz for file test 
Searching directory etc for file test 

如何重构此函数以递归搜索所有目录和子目录中的给定文件名?

+0

你可以做这样的事情,推目录堆栈中。如果没有找到,你可以弹出一个目录,“cd”,等等,就像实现一个BFS一样。 – lU5er

+0

“*我如何重构此方法以便递归搜索*”何时您将调用算法(或其实现,也许作为函数)是“递归”? – alk

+0

@alk取决于你想告诉我什么?我也用函数替换了方法,我的不好。 – chx28464

回答

0

正如许多人在评论中指出的那样。您的代码不会递归调用缺少的递归调用(函数调用自身)。你有很多错误。不检查各种系统调用的错误并忘记关闭目录流。我不知道你想用你的各种参数int depth,bool verbose达到什么目的。但是,这是查找特定文件的另一种方法,在成功时返回0 --> EXIT_SUCCESS,并在失败时返回1 -->EXIT_FAILURE

的各种方式事情都可能出错使用系统调用时,其中一些设置errnos,看他们是重要的,打印到STDERR

#include <stdio.h> 
#include <stdlib.h> 
#include <dirent.h> 
#include <errno.h> 
#include <string.h> 


#define DEBUG 1 

static int search(char *path,const char *file){ 
    DIR *dir; 
    char *slash = "/"; 

    int ret = 1; 

    struct dirent *entry; 
//checking if it failed to open and report errors to STDERR 
    if((dir = opendir(path)) == NULL){ 
     fprintf(stderr,"opendir: %s\n",strerror(errno)); 
     return EXIT_FAILURE; 
    } 

    while ((entry = readdir(dir))){ 

//if is . or .. we continue to prevent winging back and forth 

     if(strcmp(entry->d_name,".") == 0 || strcmp(entry->d_name,"..") == 0) 
      continue; 

//we check if the path has already a/if not we add one 

     int length = strlen(path); 

     if(path[length-1] != '/'){ 
      slash = "/"; 
     } 

     length += strlen(entry->d_name)+2; 
     char *newpath = malloc(length); 
     if (!newpath){ 
      fprintf(stderr,"malloc: %s\n",strerror(errno)); 
      break; 
     } 

     snprintf(newpath,length,"%s%s%s",path,slash,entry->d_name); 

     if(strcmp(entry->d_name,file) ==0){ 
#if DEBUG 
      printf("Was found here %s\n",newpath); 
#endif 
      ret = EXIT_SUCCESS; 
      break; 
     } 
     //checking if is a directory to do a recursive call 
     // using DT_DIR to avoid the use of lstat or stat 
     // if not directory we free the memory and move on 
     if(entry->d_type == DT_DIR) 
      search(newpath,file); 
     else{ 
      free(newpath); 
      continue; 
     } 

     free(newpath); 
    } 
    if(closedir(dir) != 0){ 
     fprintf(stderr,"closedir: %s\n",strerror(errno)); 
     return EXIT_FAILURE; 
    } 

    return ret; 

} 


int main() { 


    char *file = "algo.c"; 

    int ret = search("/",file); 

    printf("%d The file %s was %s\n",ret,file,(ret == 0 ? "found":"not found")); 



    return 0; 
} 

的调试设置为1

发现这里/Users/addodennis/CLionProjects/BluePrint/algo.c

文件algo.c发现

的调试设置为0

文件algo.c发现