省略)関数を公開その2【今度こそ】ディレクトリ下の全ファイル名取得!

アバター
MoNoQLoREATOR
記事: 284
登録日時: 14年前
住所: 東京

省略)関数を公開その2【今度こそ】ディレクトリ下の全ファイル名取得!

投稿記事 by MoNoQLoREATOR » 14年前

はい、ちゃんとした関数に修正してきました。

今回公開する関数は、フォルダ名とファイルの種類を指定すると、(その直下またはそれ以下の)該当する全ファイル名を拡張子付きで取得することができるというものです。

以下ソースコード

CODE:

#include 
#include 
#include 
#include 

using namespace std;

vector fileNs;
vector direNs;

void SearchFF(const char *direName, const char *exten, bool flaggFF){
    WIN32_FIND_DATA fData;              	//ファイル又はフォルダの情報がここに格納される
    HANDLE fHand;                   		//検索時のハンドルを格納
    {
    char seDirName[_MAX_PATH];          	//一時的にフォルダ名を記憶しておくだけ
    sprintf(seDirName,"%s\\%s",direName, exten);	//フォルダ名に\\ワイルドカード゙を連結
    fHand = FindFirstFile(seDirName, &fData);	//検索を行い、ハンドルを取得
    }
    
    //ファイル又はフォルダがみつかった ならば
    if(fHand != INVALID_HANDLE_VALUE){
        do{
                // '.'や'..'以外だった ならば
        	if(strcmp(fData.cFileName, ".") && strcmp(fData.cFileName, "..") ) {
	                //見つかったのがフォルダだった ならば
	                if(fData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
				if(flaggFF){
	
					char sFindSubDir[_MAX_PATH];    	//フォルダ名格納用
	                        
	                        	strcpy(sFindSubDir, direName);  	//検索フォルダのフルパス文字列をコピー
	                        	strcat(sFindSubDir, "\\");  		//文字列に\\を追加
	                        	strcat(sFindSubDir, fData.cFileName);	//検索結果のフォルダ名を文字列に追加
	
					direNs.push_back(sFindSubDir);		//フォルダのフルパスを記憶
					
					SearchFF(sFindSubDir, "*", 1);		// 再帰呼び出し
				}
			}
			else if(flaggFF==0) fileNs.push_back(fData.cFileName);	//ファイル名を記憶
		}

        } while(FindNextFile(fHand, &fData));
        FindClose(fHand);   //検索に使用したデータを破棄
    }
}

int PickUpFile(const char *direName, const char *exten, bool searchFlag){
	
	direNs.push_back(direName);
	
	if(searchFlag) SearchFF(direName, "*", 1);
	
	for(int i=0;i<direNs.size();i++){
	    SearchFF(direNs[i].c_str(), exten, 0);
	}
	
	return fileNs.size();
}
使用例

CODE:

int fileNumber = PickUpFile("C:\\Documents and Settings\\Administrator\\デスクトップ","*",1);
for(int i=0;i<fileNumber;i++) printf("%s\n",fileNs[i].c_str());
上記のコードでは、デスクトップ以下にあるすべてのファイル名を拡張子付きで取得し、それを順番に表示しています。


第1引数はフォルダ名。 C:¥Documents and Settings¥Administrator¥デスクトップ などと指定してください。※都合により円マークが全角ですが、実際に入力する際は半角で入力してください
ただし、 PickUpFile(   "C:¥¥Documents and Settings¥¥Administrator¥¥デスクトップ"   ,"*",1); というように入力しないと、¥の特殊な効果が発動されてしまってうまくいきませんのでご注意を。

第2引数はファイルの種類。 ? * などのワイルドカードを指定するものだと思ってください。全ファイル名を取得したければPickUpFile("C:",   "*"   ,1);というように指定すればOKです。mp3ファイルの名前だけを取得したければPickUpFile("C:",   "*.mp3"   ,1);というように指定する、といった具合です。

第3引数は、フォルダ直下 なのか フォルダ以下全て なのかを指定する値をを入れてください。
フォルダ直下・・・0
フォルダ以下・・・1
です。


取得したファイル名は、fileNsというstring型の配列変数に拡張子付きで格納されているので、自由に使ってください。(vector,stringというSTLの知識が必要です)



今度こそちゃんとしたものを作れたと思うのですが、
万が一バグなどございましたらご報告頂けると幸いです。

それと、もしこのソースコードをより軽くできる場合もぜひ教えてください。


それでは良いプログラミングライフを。ノシ
最後に編集したユーザー MoNoQLoREATOR on 2011年6月05日(日) 08:59 [ 編集 1 回目 ]

アバター
へろりくしょん
記事: 92
登録日時: 14年前

Re: 省略)関数を公開その2【今度こそ】ディレクトリ下の全ファイル名取得!

投稿記事 by へろりくしょん » 14年前

こーゆー 汎用性が高く、オーバーヘッドも高くなりがちな関数の場合、リエントラント化した方がいいですよ。