4

「if(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);
}
4

2 に答える 2

3

それは正解です。ただし、ディレクトリに移動することはないため、ディレクトリは見つかりません。

次のディレクトリ階層を考慮してください。

 a
 |
 +- b
 |  |
 |  +- c
 ...

コードは現在のディレクトリをスキャンし、「a」を見つけます。それがディレクトリであると判断し、それ自体を再帰的に呼び出し、読み取りのために "a" を開きます。これは機能します。そのスキャンは「b」というディレクトリを見つけますが、パスが現在「a/b」であるため、エントリ名のみを使用してそれを開こうとすると失敗します。

chdir()ディレクトリを開く前に( で) ディレクトリに移動することをお勧めします。つまり、できることを意味しますopendir(".")。古いパスをchdir()保存し、そのレベルの再帰が完了したときに再度出力します (再帰呼び出しを実行してさらに深くする前ではありません)。

于 2009-10-09T09:26:09.113 に答える
1

エントリはどこで定義されていますか? それはローカル変数ですか?なぜセグメンテーション違反になるのかわかりませんが、ローカル変数にする必要があるかもしれません。それがあなたを噛む一例はここにあります:

                    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 は間違った名前を出力するので、おそらくここに else を追加する必要があります。

同じことがdirpntにも当てはまります。while ループ内で getFolderContents を終了すると、閉じたディレクトリポイントで readdir を呼び出すことになり、ループから抜け出す必要があります。

しかし、bahbar で述べられているように、グローバル変数に一時変数を再帰して保存することはできません

于 2009-10-09T09:26:23.350 に答える