【C++】フォルダ内のファイル一覧取得(エクスプローラー風ソート)
コード
#include <iostream> #include <vector> #include <algorithm> #include <string> #include <Windows.h> #include <shlwapi.h> //StrCmpLogicalW #pragma comment(lib,"Shlwapi.lib") using namespace std; int main() { //wcin の文字化け対策 ios_base::sync_with_stdio(false); wcin.imbue(locale("japanese")); wcout << L"Input target Folder:"; wstring sTargetFolder; getline(wcin, sTargetFolder); if (!sTargetFolder.size()) { wcout << L"Not entered.\n"; return 0; } //スペース等を含んだパスのような場合の前後のダブルクォーテーションを除去 if ((sTargetFolder.substr(0, 1) == L"\"") && (sTargetFolder.substr(sTargetFolder.size() - 1, 1) == L"\"")) sTargetFolder = sTargetFolder.substr(1, sTargetFolder.size() - 2); //パスの末尾が "\" でない場合、"\" を付加 if (sTargetFolder.substr(sTargetFolder.size() - 1) != L"\\") sTargetFolder += L"\\"; //全ファイルを対象 sTargetFolder += L"*"; WIN32_FIND_DATA fd; HANDLE hFind = FindFirstFileExW( sTargetFolder.c_str(), FindExInfoBasic, &fd, FindExSearchNameMatch, nullptr, FIND_FIRST_EX_LARGE_FETCH); if (hFind == INVALID_HANDLE_VALUE) { wcout << L"Target not found.\n"; return 0; } vector<wstring> vFiles; do { //フォルダは除外 if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue; vFiles.push_back(fd.cFileName); } while (FindNextFileW(hFind, &fd)); FindClose(hFind); //エクスプローラー風のソート sort(vFiles.begin(), vFiles.end(), [](const wstring& ws1, const wstring& ws2) { return StrCmpLogicalW(ws1.c_str(), ws2.c_str()) < 0; }); for (const auto& v : vFiles) wcout << v << L"\n"; return 0; }
実行結果
検索対象ファイル
実行
通常のソートを使用した場合
sort(vFiles.begin(), vFiles.end());
気が向いたら、再帰して、サブフォルダも処理するやつを作るかもしれない・・・
(作りそうな気がする・・・)
参考
VBAで、FindFirstFile (Ex でないやつ)を使ったやつ
z1000s.hatenablog.com
上の記事ので紹介している記事の発展版。
VBAで、FindFirstFileEx を使ってやってるので、興味がある方はどうぞ。
www.excel-chunchun.com
sort を参考に(パクリとも言う)させていただきました。m(_ _)m
suzulang.com