C ++ recursive_directory_iterator错过了一些文件

时间:2018-12-17 19:08:47

标签: c++ recursion iterator directory c++17

我正在尝试通过Visual Studio 2017上的c ++ 17获取目录中的所有文件,但我遇到了一个非常奇怪的问题。如果我这样指定目录,我可以毫无问题地获取所有文件:

    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  

以此类推..

顺便说一句,我最近5天一直在使用C ++,并且绝对不知道导致这种现象的原因。请帮助我,现在我被困住了。

编辑:

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

否则肯定不能正常工作,大声笑?


编辑-问题已解决

按预期,使用实验库可与C ++ 14编译器一起使用。

#include <experimental/filesystem>

现在我可以毫无问题地获取所有文件了。似乎这是关于C ++ 17和文件系统库的问题。 感谢所有支持人员。

1 个答案:

答案 0 :(得分:1)

getenv()返回char*NULL。由于您在Windows上,<filesystem>wchar_t*字符串中可能运行。使用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

Code Page Identifiers

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中的Default Known Folders列表很有用。