SAK 図書館

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

VS.NET C 言語編1 - win32 コンソール、ディレクトリ検索、FindFirstFile

■Visual Studio .NET

  ・う〜ん、すっかり複雑な開発環境になってしまった。(^^;
    VB.NET もいくつかの構文仕様変更が発生しているようである。

  ・VC.NET は、VC6 で作成したコンソールアプリケーションのファイルI/O が
    .NET に移行してコンパイル後に実行すると、なぜかエラーが発生し、出力
    ファイルも一部に問題が発生する。
    バイナリI/O の入力にどうも何かの問題があるらしい。
    (テストしたのが、複雑な I/O なので、コード側の問題の可能性もある。)

  ・VC.NET で、C++ ではなく、C をコンパイルする場合、プリコンパイルヘッダ
    を使用しないようにしないと、コンパイラが正しく動作しない。

■再帰呼び出し処理 - ディレクトリ検索

  ・関数の再帰呼び出し処理(関数再帰処理) は、ツリー上のディリクトリ検索
    などでよく使用する。
    再帰処理とは、自分自身を自分がどんどん呼び出すことである。

  ・再帰処理のミソはローカル変数にある。
    何度も自分を呼んで、かつ、別の処理をするには、呼ばれる毎に重要な変数
    が、その都度作られなければならない。
    と言うのは、いつかは呼ばれた親もとの自分に戻って、次の処理をしなけれ
    ばならないからである。
    再帰をコントロールする変数を子再帰で変更すると、親もとに戻ったときに
    致命的な誤動作やエラーが発生する。

  ・次の例は、win32 I/O ベースのディレクトリツリー検索を行い、ファイルリ
    ストを出力する。リスト結果が多いので表示はせず、テキストファイルに
    直接書き込んでいる。
    コンソールプログラムとして作成しているが、win32 API ベースなので、
    通常のアプリケーションプログラムで簡単に使用できる。
    アプリケーションプログラムでは、printf 使用箇所は削除等すること。

/*
========================================================================
  ディレクトリ検索(win32 コンソール) - 再帰呼び出し処理
========================================================================
*/
// インクルードヘッダ
#include <windows.h>
#include <stdio.h>

// 定数宣言
#define MAX_STRING 1025                              // 文字列最大数

// 関数プロトタイプ
VOID GetDir(LPCTSTR fld, LPCTSTR wcd);
VOID FileJob(LPCTSTR fld, LPCTSTR wcd, LPCTSTR fnm, DWORD atr);
VOID DirJob(LPCTSTR fld, LPCTSTR wcd, LPCTSTR fnm, DWORD atr);

// グローバル変数
  TCHAR  fld[MAX_STRING] = "g:\\tmp\\";              // 検索ディレクトリ
  TCHAR  wcd[MAX_STRING] = "*.txt";                  // 検索ワイルドカード
  TCHAR  log[MAX_STRING] = "g:\\tmp\\filelist.txt";  // リスト出力ファイル
  HANDLE fno;                                        // リスト出力ハンドル
/*
========================================================================
  メイン
========================================================================
*/
int main(int argc, char **argv)
{
  int i;

// パラメタ取得
  for (i = 1; i < argc; i++) {
    switch (i) {
      case 1:
        lstrcpy(fld, argv[i]);  // 開始フォルダ
        break;
      case 2:
        lstrcpy(wcd, argv[i]);  // ワイルドカード
        break;
      case 3:
        lstrcpy(log, argv[i]);  // リスト出力ファイル
        break;
    }
  }

// 処理開始
  printf("ディレクトリ検索開始...\n");

// ファイルリスト出力用ファイルオープン
  if ((fno = CreateFile(log, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
    FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE) return -1;

// ディレクトリ検索開始
  GetDir(fld, wcd);

// ファイルリスト出力用ファイルクローズ
  CloseHandle(fno);

// 処理終了
  printf("\nディレクトリ検索終了。\n");
  return 0;
}
/*
========================================================================
  ディレクトリ取得
========================================================================
*/
VOID GetDir(LPCTSTR fld, LPCTSTR wcd)
{
  HANDLE dno;
  TCHAR  dir[MAX_STRING];
  WIN32_FIND_DATA fil;

// ファイル検索条件合成
  lstrcat(lstrcpy(dir, fld), wcd);

// ファイル検索
  if ((dno = FindFirstFile(dir, &fil)) != INVALID_HANDLE_VALUE) {
    if ((fil.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY) {
      FileJob(fld, wcd, fil.cFileName, fil.dwFileAttributes);
    }
    while(FindNextFile(dno, &fil) != 0) {
      if ((fil.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY) {
        FileJob(fld, wcd, fil.cFileName, fil.dwFileAttributes);
      }
    }
    FindClose(dno);
  }

// ディレクトリ検索条件合成
  lstrcat(lstrcpy(dir, fld), "*");

// ディレクトリ検索
  if ((dno = FindFirstFile(dir, &fil)) == INVALID_HANDLE_VALUE) return;
  if ((fil.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) {
    DirJob(fld, wcd, fil.cFileName, fil.dwFileAttributes);
  }
  while(FindNextFile(dno, &fil) != 0) {
    if ((fil.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY) {
      DirJob(fld, wcd, fil.cFileName, fil.dwFileAttributes);
    }
  }
  FindClose(dno);

// リターン
  return;
}
/*
========================================================================
  ファイル処理
========================================================================
*/
VOID FileJob(LPCTSTR fld, LPCTSTR wcd, LPCTSTR fnm, DWORD atr)
{
  TCHAR fil[MAX_STRING];
  TCHAR rec[MAX_STRING];
  DWORD rlen;

// ファイルフルパス合成
  lstrcat(lstrcpy(fil, fld), fnm);

// ファイル処理
  //printf("ファイル名: %s - %d\n", fil, atr);
  wsprintf(rec, "ファイル名: %s - %d\n", fil, atr);
  WriteFile(fno, rec, lstrlen(rec), &rlen, NULL);

// リターン
  return;
}
/*
========================================================================
  ディレクトリ処理
========================================================================
*/
VOID DirJob(LPCTSTR fld, LPCTSTR wcd, LPCTSTR fnm, DWORD atr)
{
  TCHAR dir[MAX_STRING];

// カレント、親ディレクトリスキップ
  if (strcmp(fnm, ".") == 0 || strcmp(fnm, "..") == 0) return;

// ディレクトリフルパス合成
  lstrcat(lstrcat(lstrcpy(dir, fld), fnm), "\\");

// ディレクトリ処理
  //printf("フォルダ名: %s - %d\n", dir, atr);
  printf(".");

// サブディレクトリ再帰処理
  GetDir(dir, wcd);

// リターン
  return;
}

■パソコン基礎知識 C 言語編資料
■プログラミング言語資料
■パソコン基礎知識 ハード編資料
■パソコン基礎知識 画像編資料
■パソコン基礎知識 Windows 編資料
■コンピュータシステム導入編資料
| VB | SQL | Perl | PHP | ASP | JSP | C | PC | HP | FAQ | フリーソフト |

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



Copyright (C) 1999-2017 Y.SAK