2011-08-12 16 views
2

私は指定されたディレクトリにファイル/フォルダを再帰的にリストすることを含むPOSIX Cの学習練習に取り組んでいます。このプログラムは、1つ以上のディレクトリの引数として取り込まれます。最初のディレクトリの内容をうまく列挙できますが、再帰に問題があります。再帰関数呼び出しの引数を渡す方法に何か問題がありますか?ディレクトリを再帰的にリストするUnixのcプログラム

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

void listdir(char *argv[]) 
{ 
    DIR *mydirhandle; 

    struct dirent *mydirent; 

    struct stat statinfo; 

    int n = 1; 

    while(argv[n] != NULL) 
    { 
    if((mydirhandle = opendir(argv[n])) == NULL) 
    { 
     perror("opendir"); 
     exit(1); 
    } 

    printf("%s/\n", argv[n]); 

    while((mydirent = readdir(mydirhandle)) != NULL) 
    { 
     if((strcmp(mydirent->d_name, ".") == 0) || (strcmp(mydirent->d_name, "..") == 0)) 

     { 
     continue; 
     } 

     else   
     { 
     printf("\t%s\n", mydirent->d_name); 

     //check if next entry is a directory  
     if(mydirent->d_type == DT_DIR) 
     { 
      //is current directory being passed correctly here? 
      listdir(mydirent->d_name); 
     } 
     }   
    }      
    n++; 
    closedir(mydirhandle); 
    } 
} 
int main(int argc, char *argv[]) 
{ 
    if(argc < 2) 
    { 
    printf("usage: %s <directory>\n", argv[0]); 
    return 0; 
    } 

    listdir(argv); 
    return 0; 
} 

答えて

2

再帰的な関数呼び出しを行うときに間違った型を渡しているという警告が表示されます。私は単にlistdirchar **ではなくchar *の引数にして、mainのforループを使用して、必要に応じて複数の引数をループするだけです。

5

struct direntd_nameメンバーは、問題のアイテムのベース名です。だから、あなたがこのようなディレクトリを経由している場合:

. 
.. 
where-is/ 
    pancakes/ 
     . 
     .. 
     house 

あなたはwhere-isにいるならば、あなたはlistdir("pancakes")しようとするでしょうが、あなたがlistdir("where-is/pancakes")する必要があるため、それは動作しません。

次のlistdirコールに渡すことができるようにする前に、探しているディレクトリの名前と組み合わせる必要があります。

あなたはこのようなものを交換したいと思うでしょう。このようなもので

listdir(mydirent->d_name); 

char *next_dir = malloc(strlen(argv[n]) + strlen(mydirent->d_name) + 1 + 1); 
sprintf(next_dir, "%s/%s", argv[n], mydirent->d_name); 
listdir(next_dir); 
free(next_dir); 

を別の方法として、あなたはディレクトリにchdirあなたはそれらを入力して、バックアップ後、chdir可能性があるのであなたが終わったら。

2

これにはftwを使用する必要があります。サブツリーのすべての項目でコールバックを呼び出します。このようにして、明示的な再帰の使用を避けると、コードがかなり短くなります。

関連する問題