1

depth firstアルゴリズムを使用してディレクトリをトラバースするコードを書いています。問題は、プログラムが何も表示せず、を与えることSegmentation Fault errorです。私はそれをデバッグしようとしましたが、私はまだ何かを学んでいるので、それは無価値でした。だから今、私は専門家の助けが必要です。コードは次のとおりです。

void func(char path[]);

int main(int argc, char *argv) {
    char buf[255];

    scanf("%s",buf);
    func(buf);
    return 0;
}

void func(char path[]) {
    DIR *dirp;
    struct stat states;
    struct dirent *direntp;
    printf("Inside\n");
    dirp=opendir(path);
    stat(path, &states);

    while ((direntp=readdir(dirp)) != NULL) {
        if (S_ISDIR(states.st_mode)) {
            printf("Calling Func\n");
            func(direntp->d_name);
            chdir("..");
        } else if (!S_ISDIR(states.st_mode)) {
            printf("  %s\n", direntp->d_name);
        } else if (!strcmp(direntp->d_name, ".") || !strcmp(direntp->d_name, "..")) {
            continue;
        }
    }
    return ;
}
4

2 に答える 2

1

func 内の while の前に、次のように記述します。

dirp=opendir (path);
if (!dirp)
  return;

そして、ところで、そのint main (int argc, char *argv[])

于 2012-12-15T15:51:36.677 に答える
0

stderr印刷をデバッグするには、;に印刷します。ラインバッファリングされているため、より確実に表示されます。

あなたの機能は、大まかに言って、次のとおりです。

void func(char path[])
{
    DIR *dirp;
    struct stat states;
    struct dirent *direntp;
    printf("Inside\n");
    dirp=opendir(path);
    stat(path,&states);

    while ((direntp = readdir(dirp)) != NULL)
    {
        if (S_ISDIR(states.st_mode))
        {
            printf("Calling Func\n");
            func(direntp->d_name);
            chdir("..");
        }
        else if (!S_ISDIR(states.st_mode))
        {
            printf("  %s\n",direntp->d_name);
        }
        else if (!strcmp(direntp->d_name,".") || !strcmp(direntp->d_name,".."))
        {
            continue;
        }
    }
}

chdir("..")賢明ではありません。関連するディレクトリに対してを実行したchdir()ことも、そのディレクトリが現在のディレクトリの直接のサブディレクトリであることを確認したこともありません。つまり、このコードがそのビットに到達した場合、このコードは混乱します。

あなたはそうしますstat(path, &states);が、それが機能したことを確認しません。

あなたはそうしますdirp = opendir(path);が、それが機能したことを確認しません。

stat()エントリごとに行うわけではありません。からの初期統計を継続的に使用しますpath。これはおそらくテスト時にディレクトリであるため、関数を再帰的に呼び出します。これはディレクトリであるを読み取ります。最初にポインタ.が不足していなければ、スタックが不足する可能性があります。DIR

ファイルにアレンジした場合でも、ループ内のテストの順序がstat()正しくありません。これは、正しいファイル名を形成するために、今読んだ名前をディレクトリのパスに追加する必要があるため、簡単な操作ではありません。あなたのコードは:

if (is a directory)
else if (is not a directory)
else if (name is . or ..)
else ...missing...

まず、if以下else ifはすべてのオプションをカバーしているため、名前のテストとfinal(存在しない)elseは実行されません。おそらく最初に名前テストが必要です(擬似コード):

if (name is a "." or "..")
    print "Skipping";
else if (name is a directory)
{
    create "path/name" as string;
    recurse with "path/name";
}
else
    print "Skipping non-directory";

これは常にすべての反復で何かを出力することに注意してください。これは、デバッグ中は非常に重要です。予期しないことを実行するときにコードを静かにしたくはありません。

closedir();を呼び出さないことに注意してください。これは、ディレクトリ記述子が不足し、dirp使用時にクラッシュするNULL値を取得することを意味します。

擬似コードには操作が含まれていないことに注意してくださいchdir()。それらの使用については、非常に、非常に、非常に注意してください。の使用法を理解しますfchdir()

読んでftw()くださいnftw(); それらの機能が直面する複雑さについてのメモがあります。

于 2012-12-15T18:57:44.847 に答える