3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

C++でフォルダ以下にあるファイル一覧を取得し、同じグループの画像(ファイル名で判別)を配列にまとめる

Posted at

1 はじめに

学生時代はOpenCVを使って画像処理系の研究をしており、そのときに作成したC++の関数を共有します。
また、C++でフォルダ以下にあるファイル一覧を取得する方法は以下のQiitaに書いていますので、そちらを参照ください。
[C++でフォルダ以下にあるファイル一覧を取得する][1]
[1]:https://qiita.com/tes2840/items/8d295b1caaf10eaf33ad

環境:Visual Studio 2017

2 やりたいこと

フォルダ以下にあるファイル一覧を取得し、同じグループの画像(ファイル名で判別)を配列にまとめたい。
図1.png

3 ソースコード

GroupingImage.cpp
# define SAME_GROUP 0	/* 同じグループ(memcmpで文字列一致した) */

/**
* @brief		フォルダ以下の同じグループの画像をまとめる関数
*				画像の命名規則: xx.yy.拡張子(xxを同じグループの場合は同一にする)
* @param[in]	folderPath	フォルダパス
* @param[out]	fileGroups	同じグループの画像をまとめた配列
* @return		true:成功, false:失敗
* @detail		
*/
bool getImageGroups(std::string folderPath, std::vector< std::vector<std::string> >& imageGroups)
{
	bool result = false;					/* 処理結果 */
	std::vector<std::string> fileNames;	/* フォルダ内にあるファイル一覧 */

	/* フォルダパス以下にあるファイル一覧を取得する */
	result = getFileNames(folderPath, fileNames);

	/* ファイル一覧の取得に失敗した場合はfalseを返す */
	if (result == false) {
		return false;
	}

	/* ファイル一覧から同じグループのファイルを動的配列にまとめる
	*  画像の命名規則: xx.yy.拡張子とし、xxを判別用パスとする
	*  判別用パスが同一なら同じグループの画像である
	*/
	const std::string distinction = ".";						/* 判別用文字 */
	std::vector<std::string>::iterator it = fileNames.begin();

	while (it != fileNames.end()){
		std::vector<std::string> sameImageGroup;				/* 同じ画像のグループ */
		std::string searchStr = *it;							/* 判別する画像のパス */
		size_t searchStrPos = 0;								/* 判別用文字の位置 */

		/*配列の先頭の画像をグループに追加し、追加した画像はファイル一覧から削除する */
		sameImageGroup.push_back(*it);						
		it = fileNames.erase(it);

		/* 判別用文字の位置を取得する */
		searchStrPos = searchStr.find(distinction);
		
		/* ファイル一覧から同じグループのものを取得する */
		std::vector<std::string>::iterator tempIt = it;
		while (tempIt != fileNames.end()){
			int result = std::memcmp(searchStr.c_str(), tempIt->c_str(), searchStrPos);

			if (result == SAME_GROUP){
				/* 同じグループの画像を配列に追加し、ファイル一覧から削除する */
				sameImageGroup.push_back(*tempIt);
				tempIt = fileNames.erase(tempIt);

				/* すでに削除しているイテレータを参照しているため更新する */
				it = tempIt;
			}
			else{
				/* 同じグループでない場合はイテレータを進める */
				tempIt++;
			}
		}

		/* グループを追加する */
		imageGroups.push_back(sameImageGroup);
	}

	return true;
}

/**
* @brief フォルダ以下のファイル一覧を取得する関数
* @param[in]	folderPath	フォルダパス
* @param[out]	fileNames	ファイル名一覧
* return		true:成功, false:失敗
*/
bool getFileNames(std::string folderPath, std::vector<std::string> &fileNames)
{
	using namespace std::filesystem;
	directory_iterator iter(folderPath), end;
	std::error_code err;

	for (; iter != end && !err; iter.increment(err)){
		const directory_entry entry = *iter;

		fileNames.push_back( entry.path().string() );
		printf("%s\n", fileNames.back().c_str());
	}

	/* エラー処理 */
	if (err){
		std::cout << err.value() << std::endl;
		std::cout << err.message() << std::endl;
		return false;
	}

	return true;
}

4 出力結果

同じグループの画像のパスを一つの配列にまとめています。そして、そのグループを配列に格納した2次元配列で出力します。
無題3.png

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?