Skip to content
Jeffrey Carpenter edited this page Aug 28, 2026 · 1 revision
// c++14 wide to utf8

#include <iostream>
#include <string>
#include <vector>
#include <cwchar>
#include <clocale>

std::string WideToUtf8(const std::wstring& wstr) {
    if (wstr.empty()) return "";

    // Set the system default or a specific UTF-8 locale
    std::setlocale(LC_CTYPE, ".UTF-8"); 

    std::mbstate_t state = std::mbstate_t();
    const wchar_t* src = wstr.c_str();

    // 1. Determine the required buffer size
    size_t len = std::wcsrtombs(nullptr, &src, 0, &state);
    if (len == static_cast<size_t>(-1)) {
        throw std::runtime_error("Conversion failed: Invalid multibyte sequence.");
    }

    // 2. Allocate space (len does not include null-terminator)
    std::vector<char> buffer(len + 1);

    // 3. Perform the actual conversion
    src = wstr.c_str(); // Reset pointer
    std::wcsrtombs(buffer.data(), &src, buffer.size(), &state);

    return std::string(buffer.data(), len);
}
// C++14 wstring_convert

#include <string>
#include <codecvt>
#include <locale>

std::string WideToUtf8Cxx14(const std::wstring& wstr) {
    // Note: This relies on <codecvt>, which is deprecated in C++17 onwards
    std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
    return converter.to_bytes(wstr);
}
// Win32 API call for wide to utf8

#include <windows.h>
#include <string>
#include <vector>

std::string WindowsWideToUtf8(const wchar_t* wstr) {
    if (!wstr || wstr[0] == L'\0') return "";

    // 1. Get required buffer size for UTF-8 (CP_UTF8)
    int size_needed = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, nullptr, 0, nullptr, nullptr);
    if (size_needed <= 0) return "";

    // 2. Allocate buffer
    std::string result(size_needed - 1, 0); // -1 to omit the null terminator

    // 3. Perform conversion
    WideCharToMultiByte(CP_UTF8, 0, wstr, -1, &result[0], size_needed, nullptr, nullptr);

    return result;
}

Clone this wiki locally