std::wstring转std::string失败:UTF-8希腊文乱码求助
编辑说明: 我补充了代码以更清晰地说明问题,同时将输入字符串从日文改为希腊文,请注意这一点,非常感谢!
问题:std::wstring转std::string时希腊文出现乱码
我有如下std::wstring输入:
wstring command = L"Σὲ γνωρίζω ἀπὸ τὴν κόψη";
以下是用于将std::wstring转换为std::string的现有代码(注:此代码并非我编写):
string wstring2string(const wstring& str) { string str2(str.length(), L' '); std::copy(str.begin(), str.end(), str2.begin()); return str2; }
经过该函数转换后,std::string中的值变为:
£r ³½ÉÁw¶É

该函数处理非UTF-8、非Unicode文本时正常,但我无法理解为何无法处理UTF-8文本。
原因分析与解决方法
问题根源
现有代码的核心错误是直接将宽字符逐字节拷贝到窄字符串:
std::wstring的每个元素是宽字符(通常为2字节UTF-16或4字节UTF-32编码的Unicode字符)std::string的每个元素是单字节字符,直接拷贝会把宽字符的每个字节拆出来单独作为窄字符,完全破坏了原Unicode编码结构,必然导致乱码。
你提到的"非UTF-8/Unicode文本正常",本质是这类文本的字符编码在单字节覆盖范围内(比如ASCII),宽字符的高位字节为0,拷贝后刚好对应正确的单字节字符。
正确的转换方案
宽字符串转窄字符串的核心是编码转换——将宽字符的Unicode编码(如UTF-16)转换为窄字符串使用的UTF-8编码,推荐两种可靠实现:
方案1:C标准库实现(C11+)
#include <codecvt> #include <locale> std::string wstring_to_utf8(const std::wstring& wstr) { std::wstring_convert<std::codecvt_utf8<wchar_t>> converter; return converter.to_bytes(wstr); }
注:MSVC原生支持,GCC部分版本需额外配置locale,或者改用跨平台方案。
方案2:系统原生API(跨平台兼容)
- Windows平台:使用
WideCharToMultiByte指定UTF-8编码
#include <windows.h> std::string wstring_to_utf8(const std::wstring& wstr) { int buf_size = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, nullptr, 0, nullptr, nullptr); std::string str(buf_size, 0); WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, &str[0], buf_size, nullptr, nullptr); str.pop_back(); // 移除自动添加的终止符 return str; }
- Linux/macOS平台:设置UTF-8 locale后使用
wcstombs
#include <cstdlib> #include <clocale> std::string wstring_to_utf8(const std::wstring& wstr) { setlocale(LC_ALL, "en_US.UTF-8"); size_t buf_size = wcstombs(nullptr, wstr.c_str(), 0) + 1; std::string str(buf_size, 0); wcstombs(&str[0], wstr.c_str(), buf_size); str.pop_back(); return str; }
验证结果
使用正确的转换函数后,std::string会存储标准UTF-8编码的希腊文字符,无论输出、存储还是后续处理都能正常显示。
内容的提问来源于stack exchange,提问作者DM Perez
相关产品推荐
相关产品推荐

