SAK 図書館
パソコン基礎知識 C 言語編 (その九) 再帰呼び出し処理 - ディレクトリ検索
win32 版については、 『VS.NET C 言語編1 - win32 コンソール、ディレクトリ検索、FindFirstFile』 を参考にして下さい。 ■再帰呼び出し処理 - ディレクトリ検索 ・関数の再帰呼び出し処理(関数再帰処理) は、ツリー上のディリクトリ検索 などでよく使用する。 再帰処理とは、自分自身を自分がどんどん呼び出すことである。 あまり複雑な再帰処理を行うと昔の PC ではスタックオーバフローが発生し たが、最近の PC では、OS が違うのでかなり複雑な再帰処理が行える。 ・再帰処理のミソはローカル変数にある。 何度も自分を呼んで、かつ、別の処理をするには、呼ばれる毎に重要な変数 が、その都度作られなければならない。 と言うのは、いつかは呼ばれた親もとの自分に戻って、次の処理をしなけれ ばならないからである。 再帰をコントロールする変数を子再帰で変更すると、親もとに戻ったときに 致命的な誤動作やエラーが発生する。 ・次の例は、DOS I/O ベースのディレクトリツリー検索を行い、ファイルリス トを出力する。リスト結果が多いので表示はせず、テキストファイルに直接 書き込んでいる。 再帰関数の考え方は、言語や OS を問わず共通であるので、Windows API に 置き換えれば、WIN32 用のディレトクリ検索にもできる。 /* ======================================================================== ディレクトリ検索 - 再帰呼び出し処理 ======================================================================== */ // インクルードヘッダ #include <stdio.h> #include <string.h> #include <dir.h> #include <dos.h> // 関数プロトタイプ int main(void); int GetDir(const char *fld, const char *wcd); int FileJob(const char *fld, const char *wcd, const char *fnm, int atr); int DirJob(const char *fld, const char *wcd, const char *fnm, int atr); // グローバル変数 FILE *fno; // ファイルリスト出力ハンドル /* ======================================================================== メイン ======================================================================== */ int main(void) { char fld[200] = "g:\\tmp\\"; // 検索開始ディレクトリ char wcd[200] = "*.txt"; // 検索ワイルドカード // 処理開始 printf("処理開始...\n"); // ファイルリスト出力用ファイルオープン if ((fno = fopen("g:\\tmp\\filelist.txt", "w")) == NULL) return -1; // ディレクトリ検索開始 GetDir(fld, wcd); // ファイルリスト出力用ファイルクローズ fclose(fno); // 処理終了 printf("処理終了。\n"); return 0; } /* ======================================================================== ディレクトリ取得 ======================================================================== */ int GetDir(const char *fld, const char *wcd) { char dir[200]; struct ffblk fil; // ファイル検索条件合成 strcat(strcpy(dir, fld), wcd); // ファイル検索 if (findfirst(dir, &fil, FA_RDONLY | FA_HIDDEN | FA_SYSTEM | FA_ARCH) != -1) { FileJob(fld, wcd, fil.ff_name, fil.ff_attrib); while(findnext(&fil) == 0) { FileJob(fld, wcd, fil.ff_name, fil.ff_attrib); } } // ディレクトリ検索条件合成 strcat(strcpy(dir, fld), "*.*"); // ディレクトリ検索 if (findfirst(dir, &fil, FA_DIREC) == -1) return 0; if ((fil.ff_attrib & FA_DIREC) == FA_DIREC) { DirJob(fld, wcd, fil.ff_name, fil.ff_attrib); } while(findnext(&fil) == 0) { if ((fil.ff_attrib & FA_DIREC) == FA_DIREC) { DirJob(fld, wcd, fil.ff_name, fil.ff_attrib); } } // リターン return 1; } /* ======================================================================== ファイル処理 ======================================================================== */ int FileJob(const char *fld, const char *wcd, const char *fnm, int atr) { char fil[200]; // ファイルフルパス合成 strcat(strcpy(fil, fld), fnm); // ファイル処理 fprintf(fno, "ファイル名: %s - %d\n", fil, atr); // リターン return 1; } /* ======================================================================== ディレクトリ処理 ======================================================================== */ int DirJob(const char *fld, const char *wcd, const char *fnm, int atr) { char dir[200]; // カレント、親ディレクトリスキップ if (strcmp(fnm, ".") == 0 || strcmp(fnm, "..") == 0) return 1; // ディレクトリフルパス合成 strcat(strcat(strcpy(dir, fld), fnm), "\\"); // ディレクトリ処理 //fprintf(fno, "フォルダ名: %s - %d\n", dir, atr); // サブディレクトリ再帰処理 GetDir(dir, wcd); // リターン return 1; } ■パソコン基礎知識 C 言語編資料
■プログラミング言語資料
■パソコン基礎知識 ハード編資料
■パソコン基礎知識 画像編資料
■パソコン基礎知識 Windows 編資料
■コンピュータシステム導入編資料