I'm facing an issue while attempting to fetch all filenames from a directory. The problem arises when handling certain strings, resulting in errors. Below is the code snippet:
#include <filesystem>int main(){ const char* dir = "D:\\Music"; std::vector<std::string> musicList; for (const auto& entry : std::filesystem::recursive_directory_iterator(dir)) { if (entry.is_regular_file()) { musicList.emplace_back(entry.path().string()); } }}
The issue occurs at entry.path().string()
when processing strings like L"D:\\Music\\suki\\Angel Note - 月明かりは優しく・・・.mp3"
. The program terminates with an error pointing to:
_STD_BEGIN// We would really love to use the proper way of building error_code by specializing// is_error_code_enum and make_error_code for __std_win_error, but because:// 1. We would like to keep the definition of __std_win_error in xfilesystem_abi.h// 2. and xfilesystem_abi.h cannot include <system_error>// 3. and specialization of is_error_code_enum and overload of make_error_code// need to be kept together with the enum (see limerick in N4950 [temp.expl.spec]/8)// we resort to using this _Make_ec helper._NODISCARD inline error_code _Make_ec(__std_win_error _Errno) noexcept { // make an error_code return { static_cast<int>(_Errno), _STD system_category() };}[[noreturn]] inline void _Throw_system_error_from_std_win_error(const __std_win_error _Errno) { _THROW(system_error{ _Make_ec(_Errno) }); // Here occur error!}_STD_END
I compiled the code in Visual Studio 2022, and the C++ standard is C++17.
Upon investigation, I simplified the issue with:
#include <filesystem>int main(){ std::filesystem::path path = L"・"; auto str = path.string();}
Similar issues arose at path.string()
. Upon further simplification using L"\u30FB"
, I discovered the character ・
is represented as "\u30FB"
.
While path.wstring()
, path.u8string()
, and other string conversions work well, I need a char*
for APIs such as ImGui::Text(str)
or FMOD's API. Attempts to convert wstring
to string
using codecvt
, Win32 API, or ICU resulted in garbled text like "・"
:
#include <filesystem>#include <Windows.h>std::string ws2s(const std::wstring& wstr){ int len = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, nullptr, 0, nullptr, nullptr); std::string str; str.reserve(len); WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, str.data(), len, nullptr, nullptr); return str;}int main(){ std::filesystem::path path = L"\u30FB"; auto str = ws2s(path.wstring());}
The resulting str was "・"
instead of "\u30FB"
.
Is there a reliable method to handle this situation effectively?