[英]How to use recursive_directory_iterator(..) without exceptions in C++
[英]C++ recursive_directory_iterator miss some files
我正在尝试通过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和文件系统库的问题..感谢所有支持人员。
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
const char CP_UTF_16LE[] = ".1200";
setlocale(LC_ALL, CP_UTF_16LE);
_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中的“ 默认已知文件夹 ”列表很有用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.