direntは、ディレクトリまたはファイルであるかどうかをテストするのstat()関数を使用する正しい方法は何ですか?
-
20-09-2019 - |
質問
私は 'もし(S_IFDIR(stbuf.st_mode))' 行といくつかの問題を抱えています。これは再帰的にするディレクトリをテストするための正しい方法は何ですか?現時点ではこの関数は右の1つのまたは2のループのためにそれを行うように見えるし、その後、失敗し、セグメンテーションフォールトます。
私は、次の条件として、おそらくより試してみた。
S_ISDIR(st_mode)
((st_mode & ST_IFMT) == S_IFDIR)
S_IFDIR(stbuf.st_mode)
私は問題が別の場所にあるかもしれない心配だから私は、全体の機能を用意しました。
void getFolderContents(char *source, int temp){
struct stat stbuf;
int isDir;
dirPnt = opendir(source);
if(dirPnt != NULL){
while(entry = readdir(dirPnt)){
char *c = entry->d_name;
if(strcmp(entry->d_name, cwd) == 0 || strcmp(entry->d_name, parent) == 0){
}
else{
stat(entry->d_name, &stbuf);
printf("%i %i ", S_IFMT, stbuf.st_mode);
if(S_IFDIR(stbuf.st_mode)){ //Test DIR or file
printf("DIR: %s\n", entry->d_name);
getFolderContents(entry->d_name, 0);
}
printf("FILE: %s\n", entry->d_name);
}
}
closedir(dirPnt);
}
解決
はい、それは正しいのです。あなたがディレクトリに変更はありませんので、しかし、あなたはそれを見つけることができません。
以下のディレクトリ階層を考えてみます:
a
|
+- b
| |
| +- c
...
あなたのコードは、現在のディレクトリをスキャンし、「A」を検索します。それがディレクトリであることを決定し、そして自分自身を再帰的に呼び出し、「」読み込み用にオープンします。これは動作します。パスは今、「A / B」であるので、そのスキャンは、「B」と呼ばれるディレクトリを検索しますが、エントリ名を使用して、それを開こうとすると、唯一の失敗します。
私はそれを開く前に(chdir()
付き)ディレクトリに変更することをお勧めします。それはあなただけopendir(".")
できることを意味します。古いパスを保管し、そのレベルを再帰とき(ない深い行くために再帰呼び出しを行う前に)行われ再びchdir()
ます。
他のヒント
どこのエントリが定義されていますか?それはローカル変数のですか? 私はそれがセグメンテーションフォールトなぜ見ることはできませんが、あなたはそれのローカル変数にする必要があるかもしれません。 それはあなたをかむ一つの例はここにあります:
if(S_IFDIR(stbuf.st_mode)){ //Test DIR or file
printf("DIR: %s\n", entry->d_name);
getFolderContents(entry->d_name, 0);
}
printf("FILE: %s\n", entry->d_name);
printf関数は、おそらくここで他を追加する必要がありますのでつもりが、間違った名前を印刷している。
同じことがdirpntとの真のです。あなたは、whileループ内getFolderContentsの外に出るときは、 あなたは、ループの外にあなたを取得する必要があります閉じdirpoint、上のreaddirを呼び出してしまう。
しかしbahbarで述べたように: あなたは再帰とグローバル変数に一時変数を格納することはできません。