C ++ Рекурсивный поиск файлов с определенными расширениями - PullRequest
0 голосов
/ 25 октября 2019

Я пытаюсь написать функцию для получения std::set расширений файлов и рекурсивно искать файлы с любым из этих расширений, записывая пути к файлу:

auto get_files(_In_ const std::wstring root, // root dir of search
        _In_ const std::set<std::string> &ext, // extensions to search for)
        _Out_ std::wofstream &ret /* file to write paths to */) -> int
{
    HANDLE find = INVALID_HANDLE_VALUE;

    // check root path
    {
        LPCWSTR root_path = root.c_str();
        DWORD root_attrib = GetFileAttributesW(root_path);
        if(root_attrib == INVALID_FILE_ATTRIBUTES) return 1; // root doesn't exist
        if(!(root_attrib & FILE_ATTRIBUTE_DIRECTORY)) return 2; // root isn't a directory
    }

    LPCWSTR dir;
    WIN32_FIND_DATAW fd;

    // dir concat
    {
        std::wstring x = root.c_str();
        x.append(L"\\*");
        dir = x.c_str();
    }


    find = FindFirstFileW(dir, &fd);

    do {
        if(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) // current file is a dir
            get_files(dir, ext, ret);
        else {
            LPCWSTR current_ext = PathFindExtensionW(fd.cFileName);
            if(ext.find(current_ext) != ext.end()) {
                ret << fd.cFileName << '\n';
            }
        }
    } while (FindNextFileW(find, &fd) != 0);

    FindClose(find);

    return 0;

}

Я получаюследующие ошибки:

E0304 нет экземпляра перегруженной функции "std :: set <_Kty, _Pr, _Alloc> :: find [with _Kty = std :: string, _Pr = std :: less,_Alloc = std :: allocator] "соответствует списку аргументов

и этому.

C2664 'std :: _ Tree_const_iterator >> std :: _ Tree> :: find (const std :: basic_string, std :: allocator> &) const': невозможно преобразовать аргумент 1 из 'const wchar_t* 'to' const std :: basic_string, std :: allocator> & '

1 Ответ

0 голосов
/ 28 октября 2019

Две проблемы:

  1. Конфликт типов между std::set<std::string> &ext и LPCWSTR current_ext. Вы можете использовать std::set<std::wstring> &ext для устранения ошибки E0304.
  2. Как указал @Botje, обратите внимание на рабочую область std::wstring x. Вы можете удалить внешнюю скобку.

Следующий код успешно скомпилирован для меня. Пожалуйста, проверьте:

#include <shlwapi.h>
#include <set>
#include <fstream>

auto get_files(_In_ const std::wstring root, // root dir of search
    _In_ const std::set<std::wstring> &ext, // extensions to search for)
    _Out_ std::wofstream &ret /* file to write paths to */) -> int
{
    HANDLE find = INVALID_HANDLE_VALUE;

    // check root path
    {
        LPCWSTR root_path = root.c_str();
        DWORD root_attrib = GetFileAttributesW(root_path);
        if (root_attrib == INVALID_FILE_ATTRIBUTES) return 1; // root doesn't exist
        if (!(root_attrib & FILE_ATTRIBUTE_DIRECTORY)) return 2; // root isn't a directory
    }

    LPCWSTR dir;
    WIN32_FIND_DATAW fd;

    // dir concat
    std::wstring x = root.c_str();
    x.append(L"\\*");
    dir = x.c_str();

    find = FindFirstFileW(dir, &fd);

    do {
        if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) // current file is a dir
            get_files(dir, ext, ret);
        else {
            LPCWSTR current_ext = PathFindExtensionW(fd.cFileName);
            if (ext.find(current_ext) != ext.end()) {
                ret << fd.cFileName << '\n';
            }
        }
    } while (FindNextFileW(find, &fd) != 0);

    FindClose(find);

    return 0;
}

Что касается второй ошибки C2664 Я не могу воспроизвести ее. Убедитесь, что вы отправили точный код, который воспроизводит вам эти две ошибки.

...