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