c:ディレクトリ内のすべてのファイル名を返す

サブディレクトリ内のファイルを含むディレクトリ内のすべてのファイル名を返す関数を書き込む方法。 これまでのところ、私はこのようなものを持っていますが、正しく機能しません。この関数を呼び出して各要素を出力します。最初の要素のみが出力されます。

誰かが私が間違っていることや、この機能を書く他のアプローチを教えてもらえますか?

char **allFiles(char *dir, OPTIONS opts) {
        char **allfiles = malloc(sizeof(char **));
        struct dirent *dp;

        while((dp = readdir(dirp)) != NULL) {

            if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0)
                continue;
            if (dp->d_type == DT_DIR)
                allfiles = allFiles(strcat(strcat(dir, "/"), dp->d_name));

            if (dp->d_type != DT_DIR)
                *allfiles = strdup(strcat(strcat(strdup(dir), "/"), dp->d_name));

            ++allfiles;
        }
    closedir(dirp);
    return allfiles;
}
1
再び標準的な質問 - 「正しく動作しない」とはどういう意味ですか?
追加された 著者 Kiril Kirov,
ftw()やnftw()の呼び出しを使ってこの作業を簡単に行うことができます。
追加された 著者 Matvey Aksenov,
あなたはリンクされたリストを使うべきです
追加された 著者 Mickael Ciocca,

3 答え

allfiles []配列は、親子と再帰子の両方で埋められます。子はそれに挿入されますが、結果は親によって上書きされます。

更新:再読み込みした後、私は配列管理がOKであることを確認します(おそらくそれが終了してしまうかもしれません) たぶんあなたはファイル記述子を使い果たしたでしょうか?

UPDATE2:置換

if (dp->d_type != DT_DIR)
        *allfiles = strdup(strcat(strcat(strdup(dir), "/"), dp->d_name));
        ++allfiles;

によって:

if (dp->d_type != DT_DIR)
        *allfiles++ = strdup(strcat(strcat(strdup(dir), "/"), dp->d_name));
2
追加された
私はwhileループでreallocを試しましたが、実行時にmalloc:***オブジェクトのエラーが発生しました。0x100800968:realloc'dが割り当てられていませんでした。*** malloc_error_breakにブレークポイントを設定してデバッグを中止しました。
追加された 著者 xiaofan2406,
@ MichaelKrelin-hacker:allfilesの再割り当てがどうやって間違っているのか分かりますが、それを修正する方法はまだ分かりません。
追加された 著者 xiaofan2406,
私は交換を試みた、それはまだ1つの要素だけを与える
追加された 著者 xiaofan2406,
@wildplasser:plsは、パス、strdup(strcat(strdup(dir)、 "/")、dp-> d_name))を含むファイル名を取得できる方法を他の人に教えてくれます。私はそれを好きではない
追加された 著者 xiaofan2406,
@ MichaelKrelin-hacker:私は、allfilesポインタをインクリメントするため、allfiles = allFiles(strcat(strcat(dir、 "/")、dp-> d_name))、次のファイル名を追加し続けます
追加された 著者 xiaofan2406,
Xiaofan、それは自明ではない。あなたは前もってサイズを知らず、データなどを追加するなどの理由で、再割り当てするでしょう。単純ですが、魔法はありませんが、自明ではないので、私は仕事をしなければなりません。
追加された 著者 Michael Krelin - hacker,
Xiaofanでは、何が起こっているのかを理解するために、コードをステップごとに解釈してみることを検討する必要があります。
追加された 著者 Michael Krelin - hacker,
私はallfilesの再割り当てがさらに攻撃的であると言います。
追加された 著者 Michael Krelin - hacker,
1つの要素は、ポインタが返されるまでに配列の終わりを指しているためです。
追加された 著者 Michael Krelin - hacker,
親と子の両方でポインタ配列のサイズを変更する必要があります。 strcen/strdup monstrumは、strlen(dir)+ strlen(entry)+ 2バイトとstrcpy/memcpyを適切な場所に割り当てることによって対処することができます。
追加された 著者 wildplasser,
フラグメントを完全に解析するには、フラグメントに多すぎるエラーがあります。私は "strdup(strcat(strcdu(strdup(dir)"/")、dp-> d_name)を見たこともなかった);"私は静かにそれをコピーして貼り付けました。一口、コーヒー。
追加された 著者 wildplasser,
ミッシェルの反応を参照してください。配列には要素が1つしかありません。ポインタを増分することはできますが、それはあなたの配列を超えています。また、再帰呼び出しからの戻り値は親のポインタを上書きし、親の1要素配列にアクセス不能にします。
追加された 著者 wildplasser,
私は誤解しました。私はalfiles []配列が再帰的なすべてに渡されることを期待しました。フラグメントに複数のエラーがあります...
追加された 著者 wildplasser,

プラットフォームにそれがある場合、 glob()の使用を検討しましたか?

0
追加された
glob()を使用している場合、現在のディレクトリをサブディレクトリに変更するにはどうすればよいですか?
追加された 著者 xiaofan2406,
おっと、私は実際にあなたのコードを読んでいなかったので、あなたはサブディレクトリに再帰したいと気付かなかった。問題は、合理的な結果を生み出さないallfilesを再割り当てして増やすことです。
追加された 著者 Michael Krelin - hacker,
こっちも一緒。ポイントは、コードは実際に動作するものによく似ていますが、複数の場所では間違っています。
追加された 著者 wildplasser,

1つのポインタ( char * )を保持するスペースしか割り当てられていないため、 allfiles ポインタを増やすことはできません。もう1つの問題は、ディレクトリが見つかったときに allfiles が上書きされてしまうためです(以前に見つかったすべてのファイルとディレクトリが失われてしまいます)。

0
追加された