SAK 図書館
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 編資料
■コンピュータシステム導入編資料