I was working on a bigger project using the recursive_directory_iterator
of std::filesystem
, when I stumbled upon this seemingly unknown/unfixable error.
I simplified the project to the bare minimum to recreate the error. Another questioner found a solution in providing the skip_permission_denied
option, which does nothing for me.
The exception is not limited to this file, it happens for random other files too, if I delete this one, for instance. Though it occurs for the same file every time if I decide not to delete it.
If I use the continue button on Visual Studio three times, it is actually able to continue the traversal of files.
What would be a proper way to address this error? And what could potentially cause this?
I removed all exception handling for readability, but the error occurs at the start of the for
loop once it reaches this file.
#define NOMINMAX
#include <string>
#include <iostream>
#include <filesystem>
#include <windows.h>
#include <fstream>
#include <winbase.h>
#include <numeric>
#include <string_view>
#include <vector>
#include <shlobj_core.h>
//#include <combaseapi.h>
namespace fs = std::filesystem;
using namespace std;
void startWinXSearch(string argv)
{
string pathToFolder = argv;
cout << pathToFolder << endl;
for (auto& el : std::filesystem::recursive_directory_iterator(pathToFolder, std::filesystem::directory_options::skip_permission_denied)) {
cout << el << endl;
}
}
int main(int argc, char* argv[])
{
CoInitializeEx(NULL, COINIT_MULTITHREADED);
string test = "C:\\Sciebo";
startWinXSearch(test);
}
UPDATE: This is what I get from using wcout
. No idea what this is supposed to mean. Is it that there's an invisible file there?!
The Error thrown currently is No mapping for the Unicode character exists in the target multi-byte code page
. If I find a solution or workaround I'll update it here.
FINAL UPDATE: I got it. Take a look at one of the comments ^^ It originated from invisible Unicode characters infront of a random file from my phone :D I even got a fix/workaround for it!
SOOOOOOO
I got the answer.. The problem originates from invisible (atleast for win10) unicode characters infront of a file ^^
How do you prevent that from crashing your programm? EZ, we first build our iterating for loop. EG like this:
for (auto& dirEntry : fs::recursive_directory_iterator(pathToFolder))
// Iterates over every file/folder in the path of the executable and its subdiretories
{
const std::wstring currentPath = dirEntry.path().c_str();
string output = wide_string_to_string(currentPath);
std::cout << output << endl;
}
Then we require a suited and well done wstring -> string conversion ^^ I got this one from some site I just can't find again..
std::string wide_string_to_string(const std::wstring& wide_string)
{
if (wide_string.empty())
{
return "";
}
const auto size_needed = WideCharToMultiByte(CP_UTF8, 0, &wide_string.at(0), (int)wide_string.size(), nullptr, 0, nullptr, nullptr);
if (size_needed <= 0)
{
throw std::runtime_error("WideCharToMultiByte() failed: " + std::to_string(size_needed));
}
std::string result(size_needed, 0);
WideCharToMultiByte(CP_UTF8, 0, &wide_string.at(0), (int)wide_string.size(), &result.at(0), size_needed, nullptr, nullptr);
return result;
}
Our Main would look something like this.
int main()
{
CoInitializeEx(NULL, COINIT_MULTITHREADED);
startWinXSearch("C:\\Users\\wwwgi\\OneDrive\\Dokumente\\test");
CoUninitialize();
}
Ofc you can also work with argv values, you just gotta format the raw path the appropiate way ^^ you can even use wmain + wchar_t argv[] if you like that! If you are unsure about the formatting you can try to format it with .path() and .string()/.c_string() :)