I'm writing a program that searches a file in Windows directory by it's name, starting from C:\. I use recursive_directory_iterator and path from std::filesystem. The problem is, while user input is read correctly and core logic seems fine, the program starts it's search directrly like this: C:\ -> C:\$Recycle.Bin -> C:\$Recycle.Bin\S-1-5-18 and then crushes.
My code:
#include <string>
#include <filesystem>
#include <iostream>
std::string start_path = "C:\\";
std::filesystem::path find_file_path(const std::string& file_name, std::filesystem::path file_path)
{
for (const auto& entry : std::filesystem::recursive_directory_iterator(file_path))
if (entry.is_directory())
{
auto new_path = entry.path();
if (!new_path.empty()) {
if (new_path.filename() == file_name) {
return new_path;
}
}
}
return std::filesystem::path();
}
int main()
{
std::string input_file{};
std::cout << "hello! enter file name here: ";
std::cin >> input_file;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::filesystem::path file_path = find_file_path(input_file, start_path);
std::cout << file_path;
}
I've tried using iterators, paths, strings, everything, but the code crushes in std::filesystem::filesystem_error, system_error or stack overflow.
I need to know why my code goes straight to C:\$Recycle.Bin and how to prevent that. Or if there is other errors I can't see because I'm a beginner in C++, the help would really be appreciated.
Thank you in advance.
If you want to avoid permissions exceptions the simplest way is to specify the skip_permission_denied
option when you construct the iterator.
Adding that plus exception handling I believe the code you're looking for is something like...
std::filesystem::path find_file_path(const std::string& file_name,
std::filesystem::path file_path)
{
for (const auto& entry : std::filesystem::recursive_directory_iterator(file_path, std::filesystem::directory_options::skip_permission_denied)) {
try {
/*
* Checking to see if it's the one we're searching for.
*/
if (entry.path().filename() == file_name) {
return entry.path();
}
}
catch (std::exception &ex) {
/*
* Handle exception...
*/
}
}
return {};
}
The above works for me (Linux, g++ 12.2.0, libstdc++ 6.0.20).