スポンサーリンク
#include <iostream> #include <vector> #include <filesystem> #include <regex> #include <unordered_map> struct PathList { std::vector<std::filesystem::path> directories; std::vector<std::filesystem::path> files; };
// 指定したパス内のファイル一覧を取得
PathList GetFileList(const std::filesystem::path& _path) { PathList result; if (!std::filesystem::exists(_path) || !std::filesystem::is_directory(_path)) { return result; // 存在しない場合は空を返す } for (const auto& entry : std::filesystem::directory_iterator(_path)) { if (entry.is_directory()) { result.directories.push_back(entry.path()); } else if (entry.is_regular_file()) { result.files.push_back(entry.path()); } } return result; }
// パスのファイル名からIDを取り出し、pair<size_t, path> の配列で返す std::vector<std::pair<size_t, std::filesystem::path>> GetFileIncdies(const std::vector<std::filesystem::path>& pathlist, const std::regex& pattern, std::vector<std::filesystem::path>* excep) { std::vector<std::pair<size_t, std::filesystem::path>> result; for (const auto& p : pathlist) { const std::string name = p.filename().string(); std::smatch m; if (std::regex_search(name, m, pattern)) { // パターンにマッチしたかどうか bool ok = false; size_t idx = 0; for (size_t i = 1; i < m.size(); ++i) { const std::string s = m[i].str(); if (s.empty()) continue; // すべて数字かを判定 const bool all_digits = std::all_of(s.begin(), s.end(), [](unsigned char c) { return std::isdigit(c) != 0; }); if (!all_digits) continue; try { idx = static_cast<size_t>(std::stoull(s)); ok = true; break; } catch (...) { // stoull 失敗時は次のキャプチャを試す } } if (ok) { result.emplace_back(idx, p); } else if (excep) { excep->push_back(p); } } else { if (excep) excep->push_back(p); } } // インデックス昇順、同値ならパスの辞書順 std::sort(result.begin(), result.end(), [](const auto& a, const auto& b) { if (a.first != b.first) return a.first < b.first; return a.second < b.second; }); return result; }
template<typename Tuple,typename Pair,int Index> std::unordered_map<size_t, Tuple> CreateDataSetList(std::unordered_map<size_t, Tuple>& datamap,std::vector<Tuple>& datasets, std::vector<Pair>& pairs) { for (const auto& p : pairs) { size_t idx = p.first; const auto& path = p.second; auto& tupleitem = datamap[idx]; std::get<Index>(tupleitem) = path; // Index番目にパスをセット } return datamap; }
// マップをIDでソートしたものを返す template<typename Tuple> std::vector<std::pair<size_t, Tuple>> SortByID(const std::unordered_map<size_t, Tuple>& byidmap) { std::vector<std::pair<size_t, Tuple>> sorted; sorted.reserve(byidmap.size()); for (const auto& kv : byidmap) { sorted.emplace_back(kv.first, kv.second); } std::sort(sorted.begin(), sorted.end(), [](const auto& lhs, const auto& rhs) { return lhs.first < rhs.first; // size_tキーで昇順 }); return sorted; }
using Tuple = std::tuple<std::filesystem::path, std::filesystem::path, std::filesystem::path>; using Pair = std::pair<size_t, std::filesystem::path>;
// パスとパターンからファイル一覧を作成し、インデックスとパスのペアを返す関数 std::vector<std::pair<size_t, std::filesystem::path> > GetFiles(const std::filesystem::path& path,std::regex pattern){ PathList fileList = GetFileList(path); std::vector<std::pair<size_t, std::filesystem::path> > flist; flist = GetFileIncdies(fileList.files, pattern, nullptr); return flist; }
int main() { std::vector< Tuple > dataSetList; std::vector<Pair > list_1 = GetFiles("C:\\test\\tmp\\txt", std::regex(R"(新規 テキスト000_(\d+)\.txt)") ); std::vector<Pair > list_2 = GetFiles("C:\\test\\tmp\\doc", std::regex(R"(doc_000_(\d+)\.doc)") ); std::unordered_map<size_t, Tuple> byidmap; CreateDataSetList<Tuple, Pair, 0>(byidmap, dataSetList, list_1); CreateDataSetList<Tuple, Pair, 1>(byidmap, dataSetList, list_2); std::vector<std::pair<size_t, Tuple>> sorted = SortByID(byidmap); for(const auto& b : sorted) { std::cout << "ID: " << b.first << " " << std::get<0>(b.second).filename() << " " << std::get<1>(b.second).filename() << " " << std::get<2>(b.second) << "\n"; } }