SAK 図書館

SAK Streets メインストリート 図書館・カフェ 一覧 SAK Streets 検索
| VB | SQL | Perl | PHP | ASP | JSP | C | PC | HP | FAQ | フリーソフト |

パソコン基礎知識 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 編資料
■コンピュータシステム導入編資料
| VB | SQL | Perl | PHP | ASP | JSP | C | PC | HP | FAQ | フリーソフト |

SAK Streets メインストリート 図書館・カフェ 一覧 SAK Streets 検索



Copyright (C) 1999-2017 Y.SAK