2017-04-12 152 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發現