私はCで新しく、現在の作業ディレクトリのすべてのディレクトリ/ファイルを再帰的に処理し、その情報を出力しようとしています。私が解決している良い方法について考えることができないという問題は、パスが2回目に間違って構築される同じディレクトリに2つのフォルダがある場合です。たとえば、 "/ something/dir1"の後にdir1とdir2が同じパスにある場合、パスは "/ something/dir2"になりますが、 "/ something/dir1/dir2"になります。私は以前のパスを把握していると思っていましたが、再帰呼び出しごとに常に書き直さなければ、それを行う方法がわかりません。Cのディレクトリを再帰
更新:私は元々のバグを修正して、ここに新しいコードを投稿すると考えました。 opendir( "。")とchangedir( "..")は、私が気付いていなかったトリックは実際にはその期間を完全な現在または前のパスに変換します。 type = 8とtype = 4ステートメントをより読みやすいS_ISDIR(statbuf.st_mode)ステートメントとS_ISREG(statbuf.st_mode)ステートメントに変更する限り、それらは型ステートメントでは機能しません。文法と私がそれらを使って試した方法に何が間違っているか分からない。
アップデート2:私はここS_ISDIR/S_ISREGの問題を解決 - How to use S_ISREG() and S_ISDIR() POSIX Macros?
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <dirent.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
void helper(DIR *, struct dirent *, struct stat, char *, int);
void dircheck(DIR *, struct dirent *, struct stat, char *, int);
int main(int argc, char *argv[]){
DIR *dip;
struct dirent *dit;
struct stat statbuf;
char currentPath[FILENAME_MAX];
int depth = 0; /*Used to correctly space output*/
dip = opendir(".");
getcwd(currentPath, FILENAME_MAX);
while((dit = readdir(dip)) != NULL){
/*Skips . and ..*/
if(strcmp(dit->d_name, ".") == 0 || strcmp(dit->d_name, "..") == 0)
continue;
stat(currentPath, &statbuf);
/*Checks if current item is of the type file (type 8)*/
if(dit->d_type == 8)
printf("%s (%d bytes)\n", dit->d_name, (int)statbuf.st_size);
/*Checks if current item is of the type directory (type 4)*/
if(dit->d_type == 4)
dircheck(dip, dit, statbuf, currentPath, depth);
}
return 0;
}
/*Recursively called helper function*/
void helper(DIR *dip, struct dirent *dit, struct stat statbuf, char currentPath[FILENAME_MAX], int depth){
int i = 0;
dip = opendir(currentPath);
while((dit = readdir(dip)) != NULL){
if(strcmp(dit->d_name, ".") == 0 || strcmp(dit->d_name, "..") == 0)
continue;
stat(currentPath, &statbuf);
if(dit->d_type == 8){
for(i = 0; i < depth; i++)
printf(" ");
printf("%s (%d bytes)\n", dit->d_name, (int)statbuf.st_size);
}
if(dit->d_type == 4)
dircheck(dip, dit, statbuf, currentPath, depth);
}
}
void dircheck(DIR *dip, struct dirent *dit, struct stat statbuf, char currentPath[FILENAME_MAX], int depth){
int i = 0;
strcat(currentPath, "/");
strcat(currentPath, dit->d_name);
/*If two directories exist at the same levelt the path
is built wrong and needs to be corrected*/
if((chdir(currentPath)) == -1){
chdir("..");
getcwd(currentPath, FILENAME_MAX);
strcat(currentPath, "/");
strcat(currentPath, dit->d_name);
for(i = 0; i < depth; i++)
printf (" ");
printf("%s (subdirectory)\n", dit->d_name);
depth++;
helper(dip, dit, statbuf, currentPath, depth);
}
else{
for(i =0; i < depth; i++)
printf(" ");
printf("%s (subdirectory)\n", dit->d_name);
chdir(currentPath);
depth++;
helper(dip, dit, statbuf, currentPath, depth);
}
}
あなた自身の質問に既に回答しているようです... –
@Oli:再読み込み。 OPは現在のコードにバグがあると言いました。また、これはヒープ上にたくさんのメモリを割り当てる(またはさらに悪いことに、スタック上で)代わりに、できるだけ再帰の各レベルで既存のバッファを最良に再利用する方法を学ぶ非常に有用な学習の練習になります。 –
'type == 8'? 'readdir'マンページのシンボル定数には理由があります。 – asveikau