Win APIのMultiByteToWideChar
関数、WideCharToMultiByte
関数でstring
とwstring
を相互変換するコードです。テストはしていません。
C++20からは標準ライブラリのコンバーターが非推奨なので自作するか外部ライブラリを使用する必要があります。
#include <bit> #include <string> #define STRICT #define NOMINMAX #include <Windows.h> namespace stdw32 { std::wstring to_wstring(std::string_view s, DWORD flags = 0) { auto ret = ::MultiByteToWideChar(CP_ACP, 0, std::bit_cast<LPCCH>(s.data()), s.size(), nullptr, 0); if (ret == 0) return {}; std::wstring buf(ret, L'\0'); ret = ::MultiByteToWideChar(CP_ACP, 0, std::bit_cast<LPCCH>(s.data()), s.size(), buf.data(), ret); return std::move(buf); } std::wstring to_wstring(std::u8string_view s, DWORD flags = 0) { auto ret = ::MultiByteToWideChar(CP_UTF8, 0, std::bit_cast<LPCCH>(s.data()), s.size(), nullptr, 0); if (ret == 0) return {}; std::wstring buf(ret, L'\0'); ret = ::MultiByteToWideChar(CP_UTF8, 0, std::bit_cast<LPCCH>(s.data()), s.size(), buf.data(), ret); if (ret == 0) return {}; return std::move(buf); } std::string to_string( std::wstring_view s, DWORD flags = 0, std::string_view defChar = {}, LPBOOL usedDefChar = nullptr) { auto ret = ::WideCharToMultiByte(CP_ACP, 0, s.data(), s.size(), nullptr, 0, defChar.data(), usedDefChar); if (ret == 0) return {}; std::string buf(ret, L'\0'); ret = ::WideCharToMultiByte(CP_ACP, 0, s.data(), s.size(), buf.data(), ret, defChar.data(), usedDefChar); if (ret == 0) return {}; return std::move(buf); } std::u8string to_u8string( std::wstring_view s, DWORD flags = 0, std::string_view defChar = {}, LPBOOL usedDefChar = nullptr) { auto ret = ::WideCharToMultiByte(CP_UTF8, 0, s.data(), s.size(), nullptr, 0, defChar.data(), usedDefChar); if (ret == 0) return {}; std::u8string buf(ret, L'\0'); ret = ::WideCharToMultiByte(CP_UTF8, 0, s.data(), s.size(), std::bit_cast<char*>(buf.data()), ret, defChar.data(), usedDefChar); if (ret == 0) return {}; return std::move(buf); } } int main() { auto s1{ stdw32::to_wstring("abcあ🍎") }; auto s2{ stdw32::to_wstring(u8"abcあ🍎") }; auto s3{ stdw32::to_string(L"abcあ🍎") }; auto s4{ stdw32::to_u8string(L"abcあ🍎") }; return 0; }