You can use boost::filesystem. However, this is not a header only library and you may have requirements not to link with external libraries or it may be very inconvenient to do so.
On Windows (which looks like you are) I like to use this class to get all the filenames matching given pattern.
#pragma once
#include <string>
#include <vector>
#include <windows.h>
#pragma comment(lib, "User32.lib")
#undef tstring
#undef tcout
#if defined(_UNICODE) || defined(UNICODE)
#define tstring std::wstring
#define tcout std::wcout
#else
#define tstring std::string
#define tcout std::cout
#endif
class FileFinder {
WIN32_FIND_DATA ffd;
HANDLE _handle;
public:
FileFinder(LPCTSTR pattern) { _handle = FindFirstFile(pattern, &ffd); }
~FileFinder() { FindClose(_handle); }
const TCHAR *FindFirst() const {
return _handle != INVALID_HANDLE_VALUE ? ffd.cFileName : nullptr;
}
const TCHAR *FindNext() {
return FindNextFile(_handle, &ffd) ? ffd.cFileName : nullptr;
}
std::vector<tstring> GetAllNames() {
std::vector<tstring> result;
for (auto name = FindFirst(); name; name = FindNext())
result.push_back(name);
return result;
}
};
It follows RAII paradigm and will not leak resources due to an exception.
Example of it's usage could be like this.
#include <tchar.h>
#include <iostream>
#include "FileFinder.h"
int _tmain(int argc, TCHAR *argv[]) {
DWORD dwError = 0;
if (argc != 2) {
_tprintf(TEXT("\nUsage: %s <directory name>\n"), argv[0]);
return -1;
}
tstring pattern(argv[1]);
pattern.erase(pattern.find_last_not_of(TEXT("\\")) + 1);
pattern += TEXT("\\*.pgm");
if (pattern.length() > MAX_PATH) {
_tprintf(TEXT("\nDirectory path is too long.\n"));
return -1;
}
FileFinder finder(pattern.c_str());
auto files = finder.GetAllNames();
for (const auto &f : files)
tcout << f << std::endl;
return 0;
}