2016-04-02 4 views
0

мой код не работает. Мне нужно отобразить все каталоги внутри каталога, заданного в качестве аргумента командной строки. До сих пор я попытался это:Как рекурсивно перечислить все каталоги?

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

struct stat my_stat; 

int searchDirectory (char *dirName); 

int searchDirectory(char *dirName){ 
    struct dirent *pDirent; 
    DIR *pDir; 

    pDir = opendir(dirName); 
    if (pDir == NULL) { 
     printf("Cannot open directory '%s'\n", dirName); 
     return 1; 
    } 

    while ((pDirent = readdir(pDir)) != NULL){ 
     printf("%s\n", pDirent->d_name); 
     stat(pDirent->d_name, &my_stat); 
     if (S_ISDIR(my_stat.st_mode)){ 
      searchDirectory(pDirent->d_name); 
      printf("Directory Found: %s\n", pDirent->d_name); 
     } 
    } 

    return 0; 
} 

int main(int argc, char *argv[]){ 
    struct stat my_stat; 


    if (lstat(argv[1], &my_stat) < 0){ 
     perror("stat error"); 
    } 

    if (S_ISDIR(my_stat.st_mode)){ 
     printf("Directory found\n"); 
     searchDirectory(argv[1]); 
    } 

    return 0; 
} 

Я не уверен, почему, но по какой-то причине мой код читает обычные файлы в каталоге, но S_ISDIR (my_stat.st_mode)) должны предотвратить это. Любая идея о том, что может быть неправильным?

+0

И каков ваш выход? Вы даже выполнили основную отладку printf? –

+1

Это дублированный вопрос - сложность, как всегда, заключается в том, чтобы найти вопрос о том, что это дубликат. –

+0

@JonathanLeffler no problemo: Googling точный заголовок дает: «Около 511 000 результатов», с SO Q & A на первой странице. –

ответ

2

Проблема, с которой вы сталкиваетесь, заключается в том, что pDirent->d_name относится к каталогу, в котором вы сейчас находитесь, пока вы обрабатываете рабочий каталог того, с чего вы начали процесс.

Чтобы исправить, concatename имен каталога, прежде чем делать opendir

int searchDirectory(char *dirName){ 
    ...... 
    while ((pDirent = readdir(pDir)) != NULL){ 
     printf("%s\n", pDirent->d_name); 
     stat(pDirent->d_name, &my_stat); 
     if (S_ISDIR(my_stat.st_mode)){ 
      // construct new path .... 
      char * dirname = malloc(strlen(dirName)+strlen(pDirent->d_name)+2); 
      strcat(strcat(strcpy(dirname,dirName),"/"),pDirent->d_name); 
      searchDirectory(dirname); 
      free(dirname) 
      printf("Directory Found: %s\n", pDirent->d_name); 
     } 
    } 
    ..... 

Также обратите внимание, что вам нужно обрабатывать . и .. каталогов как частные случаи, как ваш код в противном случае будет в конечном итоге в бесконечном рекурсия, так что вам нужна дополнительный код для обработки тех - см this question подробности

+0

У подозреваемого OP также будет проблема с рекурсией с 'pDirent-> d_name''. "И' ".." '. – chux

+0

Спасибо - Добавлено предупреждение в ответ – Soren

1

Вашего рекурсивного вызова searchDirectory(pDirent->d_name); неправильно, потому что вы получили имя относительно каталога вы разбор, так что вам нужно сцепить и имя каталога вы действуете синтаксический разбор и относительное (к этому каталогу) имя, которое вы получили:

char newDir[PATH_MAX]; 
snprintf(newDir,PATH_MAX,"%s/%s",dirName,pDirent->d_name); 
searchDirectory(newDir); 
+1

Лучше использовать 'snprintf'. – Chnossos

+0

@Chnossos Detail: Использование 'snprintf()' без проверки результата 'snprintf()' справляется с одной проблемой, но открывает другое как 'searchDirectory (newDir);' может иметь неожиданные результаты (открытый сбой, бесконечная рекурсия и т. Д. .) – chux

Смежные вопросы