【VC】フォルダのファイル一覧取得してリストで返す【C++】

まず、設定として

[プロジェクト(P)]

[hogehogeのプロパティ]

[構築プロパティ]

[プロジェクトの既定値]

[文字セット]

[マルチ バイト文字セットを使用する]

に設定する


練習として静的メンバ関数にしてみました

#include <iostream>
#include <sstream>
#include <vector>
#include <string>
#include <Windows.h>

using namespace std;

class Dir
{
public:
	// コンストラクタ
	Dir(void){}
	// デストラクタ
	virtual ~Dir(void){}

	// ファイル一覧取得
	// folder : フォルダの絶対パスを入力とする 
	// 例 : "D:\\Users\\Pictures\\"
	static vector<string> read(string folder){
		// 宣言
		vector<string> fileList;
		HANDLE hFind;
		WIN32_FIND_DATA fd;

		// ファイル名検索のためにワイルドカード追加
		// 例 : "D:\\Users\\Pictures\\*.*"
		stringstream ss;
		ss << folder;
		string::iterator itr = folder.end();
		itr--;
		if(*itr != '\\') ss << '\\';
		ss << "*.*";

		// ファイル探索
		// FindFirstFile(ファイル名, &fd);
		hFind = FindFirstFile(ss.str().c_str(), &fd);

		// 検索失敗
		if(hFind == INVALID_HANDLE_VALUE){
			std::cout << "ファイル一覧を取得できませんでした" << std::endl;
			exit(1); // エラー終了
		}

		// ファイル名をリストに格納するためのループ
		do{
			// フォルダは除く
			if(!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
			  && !(fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN))
			{
				//ファイル名をリストに格納
				char *file = fd.cFileName;
				string str = file;
				fileList.push_back(str);
			}
		}while(FindNextFile(hFind, &fd)); //次のファイルを探索
		
		// hFindのクローズ
		FindClose(hFind); 

		return fileList;
	}
};


使い方は

int main(int argc, char *argv[])
{
	// ファイル入力
	std::vector<std::string> backfilelist = Dir::read("D:\\Users\\Pictures\\");
	for(int i = 0; i < backfilelist.size(); i++){
		std::cout << backfilelist[i] << std::endl;
	}
	return 0;
}


出力結果は

1.png
2.png
3.png
4.png
desktop.ini
無題 (2).png
無題.png

desktop.iniが出てくることもあるので、拡張子で判別して出力されないようにする必要があります




こんな感じで組んでみました
間違い指摘はコメ欄でお願いします




[追記 : 2011-10-05]
以前記載していたものはOpenCV2.2をincludeして、なおかつReleaseモードで実行した時に動作していたので、それ以外の環境では動作しなかった
そこで、修正


#include itr--;を追加
ついでにコメントで指摘していただいた箇所 && !(fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) も追加




[追記 : 2011-11-22]
何を勘違いしていたのかパスの末尾に"\\"があるかどうかを調べるif文が全く役割を果たしていなかった
そこで、また修正

itr--;を削除
その下のif(*itr == '\\') ss << '\\';if(*itr != '\\') ss << '\\'; に変更




[追記 : 2012-01-12]
itr--;を削除したらそりゃ当然動かないです
itr--;を追加