File search starts with C:\\$Recycle.Bin\\S-1-5-18 and causes filesystem_error

76 Views Asked by At

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.

1

There are 1 best solutions below

0
G.M. On BEST ANSWER

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).