As per my earlier post How to transform between a double date-time and std::string in C++, some things are surprisingly hard in C++, especially compared to writing in a .NET language. I recently tracked down this useful snippet of code on the internet in order to recursively build a list of files matching some file extension under a folder. This only compiles on Windows – if you want something cross-platform, look at boost (I wanted to avoid bringing the boost filesystem library into my project as yet another dependency).
void accumulate_files(
const std::string& folder,
const std::string& extension,
std::vector<std::string>& file_names )
{
std::ostringstream oss;
oss << folder << "\\";
std::string search_path = oss.str();
WIN32_FIND_DATA fd;
HANDLE hFind = ::FindFirstFile( search_path.c_str(), &fd );
if( hFind != INVALID_HANDLE_VALUE)
{
do
{
std::string file_name = fd.cFileName;
std::ostringstream full_file_name;
full_file_name << folder << "\\" << file_name;
if ( boost::algorithm::ends_with( file_name, extension ) )
{
file_names.push_back( file_name );
}
else if ( file_name != "." && file_name != ".." && !file_name.empty() )
{
// Recursively call into next directory
accumulate_files( full_file_name.c_str(), extension, file_names );
}
}
while( ::FindNextFile(hFind, &fd) );
::FindClose(hFind);
}
}
For production code, you’d also want to wrap the file handle in a smart pointer to ensure it gets closed properly for exception safety.
Reblogged this on Dinesh Ram Kali..
Hi,
little typo here: ‘else if ( fie_name != “.”…’
Thanks – I’ve corrected the typo now.
Pingback: How to generate tests under GTest | musingstudio