C++中如何将存储在std::string中的UTF16内容转换为UTF8编码的std::string
UTF-16编码std::string转UTF-8编码std::string解决方案
首先需要注意:你当前持有的std::string存储的是UTF-16的原始字节,转换前需确认字节序,你给出的示例为小端(LE)UTF-16,以下方案默认适配该场景,若为大端(BE)需调整对应参数。
方案1:C++11及以上标准库实现(无第三方依赖)
需要引入<codecvt>、<locale>头文件,实现代码如下:
#include <string> #include <codecvt> #include <locale> std::string utf16le_to_utf8(const std::string& utf16_str) { // 若为大端UTF-16,将第三个模板参数改为std::codecvt_mode::big_endian即可 using ConvertType = std::codecvt_utf8_utf16<char16_t, 0x10ffff, std::codecvt_mode::little_endian>; std::wstring_convert<ConvertType, char16_t> converter; const char16_t* u16_ptr = reinterpret_cast<const char16_t*>(utf16_str.data()); size_t u16_len = utf16_str.size() / sizeof(char16_t); return converter.to_bytes(u16_ptr, u16_ptr + u16_len); }
测试调用示例:
// 你的示例输入 std::string utf16("\x04\x1f\x04\x40\x04\x38\x04\x32\x04\x35\x04\x42"); std::string utf8 = utf16le_to_utf8(utf16); // 输出的utf8即为"\xd0\x9f\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82",对应俄语单词Привет
注意:std::wstring_convert和相关的codecvt系列工具在C++17被标记为弃用,但目前所有主流编译器(GCC、Clang、MSVC)均保留完整支持,无需担心兼容性问题。
方案2:Windows平台专属Win32 API实现
如果是Windows环境开发,也可以用系统API完成转换:
#ifdef _WIN32 #include <windows.h> std::string utf16le_to_utf8(const std::string& utf16_str) { // 先把UTF16字节转成宽字符 int wchar_count = MultiByteToWideChar(CP_UTF16LE, 0, utf16_str.data(), utf16_str.size(), nullptr, 0); std::wstring wstr(wchar_count, L'\0'); MultiByteToWideChar(CP_UTF16LE, 0, utf16_str.data(), utf16_str.size(), wstr.data(), wchar_count); // 再把宽字符转成UTF8 int utf8_count = WideCharToMultiByte(CP_UTF8, 0, wstr.data(), wstr.size(), nullptr, 0, nullptr, nullptr); std::string utf8_str(utf8_count, '\0'); WideCharToMultiByte(CP_UTF8, 0, wstr.data(), wstr.size(), utf8_str.data(), utf8_count, nullptr, nullptr); return utf8_str; } #endif
注意事项
- 如果输入的UTF16包含BOM头,需要先跳过前2个字节再做转换,否则会输出多余的零宽无断空格字符。
- 若需要长期稳定的编码转换能力,也可以接入ICU等专业编码处理库,对边缘场景的兼容性更强。
内容的提问来源于stack exchange,提问作者German
相关产品推荐
相关产品推荐

