问题
I'm trying to get all files in directory through c++17 on my visual studio 2017 but I've just encountered a really weird problem. If I specify directory like this I can get all files without any problem:
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;
}
}
But I need all file list on APPDATA, and I'm trying to get path with getenv() function and when using it "recursive_directory_iterator" function skipping files:
for (auto& p : std::filesystem::recursive_directory_iterator(getenv("APPDATA"))) {
if (std::filesystem::is_regular_file(p.path())) {
std::cout << p.path() << std::endl;
}
}
Is that because of using getenv() function? Some folders that skipping when using getenv;
Mozilla
TeamWiever
NVIDIA
and so on ..
Btw, I'm using C++ last 5 days and definitely don't have any clue what causes for that behavior. Please help me, right now I'm stuck.
EDIT :
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;
}
}
}
This is also not working, seems like i must put string into function like this:
recursive_directory_iterator("C:\\Users\\r00t\\AppData\\Roaming\\Mozilla")
otherwise definitely not working, LOL ??
EDIT - PROBLEM FIXED
Using experimental library is working with C++14 compiler like as expected.
#include <experimental/filesystem>
Now i can able to get all files without problem.Seems like this is problem about C++17 and filesystem library .. Thanks for all support guys.
回答1:
getenv()
returns a char*
or NULL
. <filesystem>
is probably operating with wchar_t*
strings since you are on Windows. Use SHGetKnownFolderPath(...)
to query for where special folders are.
What happens when you run your program is probably that you hit some character that can't be displayed with your current locale ("C" if not set explicitly) so it sets your outstream in fail mode. You can however set your locale to UTF-16LE to remedy this. It works with /std:c++17 and the standard <filesystem>
header:
#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);
With that in place, the path you get from SHGetKnownFolderPath
should work:
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);
}
You may also find the list of Default Known Folders in Windows useful.
来源:https://stackoverflow.com/questions/53821593/c-recursive-directory-iterator-miss-some-files