C ++ recursive_directory_iterator пропустить некоторые файлы - PullRequest
0 голосов
/ 17 декабря 2018

Я пытаюсь получить все файлы в каталоге через c ++ 17 на моей Visual Studio 2017, но я только что столкнулся с действительно странной проблемой.Если я укажу каталог таким образом, я смогу без проблем получить все файлы:

    for (auto& p : std::filesystem::recursive_directory_iterator("C:\\Users\\r00t\\AppData\\Roaming\\Mozilla")) {
    if (std::filesystem::is_regular_file(p.path())) {
            std::cout << p.path() << std::endl;
        }
}

Но мне нужен весь список файлов в APPDATA, и я пытаюсь получить путь с помощью функции getenv () и при ее использованииФункция "recursive_directory_iterator" пропускает файлы:

    for (auto& p : std::filesystem::recursive_directory_iterator(getenv("APPDATA"))) {
    if (std::filesystem::is_regular_file(p.path())) {
            std::cout << p.path() << std::endl;
        }
}

Это из-за использования функции getenv ()?Некоторые папки, которые пропускаются при использовании getenv;

Mozilla 
TeamWiever
NVIDIA  

и т. Д. *

Кстати, я использую C ++ последние 5 дней и определенно не знаю, что является причиной этогоповедение.Пожалуйста, помогите мне, сейчас я застрял.

РЕДАКТИРОВАТЬ:

    for (auto& p : std::filesystem::directory_iterator(getenv("APPDATA"))) {
    std::string targetFolder = p.path().string();
    for (auto& targetFolderFiles : std::filesystem::recursive_directory_iterator(targetFolder)) {
        if (std::filesystem::is_regular_file(targetFolderFiles.path())) {
            std::cout << targetFolderFiles.path() << std::endl;
        }
    }
}

Это также не работает, похоже, я должен поместить строку в функцию, как это:

recursive_directory_iterator("C:\\Users\\r00t\\AppData\\Roaming\\Mozilla")

иначе определенно не работает, LOL ??


РЕДАКТИРОВАТЬ - ИСПРАВЛЕНО ПРОБЛЕМА

Использование экспериментальной библиотеки работает с компилятором C ++ 14, как и ожидалось.

#include <experimental/filesystem>

Теперь я могу получить всефайлы без проблем. Похоже, что это проблема C ++ 17 и библиотеки файловой системы. Спасибо за поддержку, ребята.

1 Ответ

0 голосов
/ 18 декабря 2018

getenv() возвращает char* или NULL.<filesystem> - это , вероятно , работающий со строками wchar_t*, поскольку вы работаете в Windows.Используйте SHGetKnownFolderPath(...), чтобы запросить, где находятся специальные папки.

Когда вы запускаете вашу программу, вероятно, вы сталкиваетесь с каким-то символом, который не может быть отображен в вашей текущей локали («C», если не задано явно), поэтому он устанавливает ваше опережение в режиме сбоя.Тем не менее, вы можете установить свой язык в UTF-16LE, чтобы исправить это.Он работает с / std: c ++ 17 и стандартным <filesystem> заголовком:

#include <Shlobj.h> // SHGetKnownFolderPath
#include <clocale>  // std::setlocale 
#include <io.h>     // _setmode
#include <fcntl.h>  // _O_U16TEXT

Идентификаторы кодовой страницы

const char CP_UTF_16LE[] = ".1200";
setlocale(LC_ALL, CP_UTF_16LE);

_setmode

_setmode(_fileno(stdout), _O_U16TEXT);

После этого путь, который вы получите от SHGetKnownFolderPath, должен работать:

PWSTR the_path;
if(SHGetKnownFolderPath(FOLDERID_RoamingAppData, KF_FLAG_DEFAULT, NULL, &the_path) == S_OK) {
    for(auto& p : std::filesystem::recursive_directory_iterator(the_path)) {
        std::wcout << p.path() << L"\n";

        // you can also detect if the outstream is in fail mode: 
        if (std::wcout.fail()) {
            std::wcout.clear();  // ... and clear the fail mode
            std::wcout << L" (wcout was fail mode)\n";
        }
    }
    CoTaskMemFree(the_path);
}

Вы также можете найти список Стандартных известных папок в Windows полезно.

...