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