CHAR数组转std::string遇特殊字符异常,求非宽字符处理方案
解决GetWindowTextA获取含特殊字符窗口标题转std::string的编码差异问题
问题场景
当窗口标题为Pesquisa de domínio GoDaddy - Brave时,执行以下代码后,发现windowTitle与直接定义的str的Base64编码不一致,核心问题出在特殊字符í的转换上:
CHAR title[256]; int r = GetWindowTextA(hwnd, title, 256); // r: 35 std::string windowTitle(title); std::string str = "Pesquisa de domínio GoDaddy - Brave"; auto s1 = QByteArray::fromStdString(windowTitle).toBase64(); auto s2 = QByteArray::fromStdString(str).toBase64();
问题根源
GetWindowTextA返回的是系统当前ANSI代码页(比如Windows-1252)的字节流,其中í对应的单字节是0xED。- 源码中直接定义的
std::string如果是UTF-8编码保存的,í对应的是双字节0xC3 0xAD。 - 两种字节表示完全不同,导致Base64编码结果不一致。
解决方案(不依赖GetWindowTextW和wstring)
核心思路是将GetWindowTextA获取到的ANSI编码字符串转换为UTF-8编码的std::string,使其与源码中直接定义的字符串字节内容一致。具体实现如下:
CHAR title[256]; int r = GetWindowTextA(hwnd, title, 256); if (r == 0) { // 处理窗口标题获取失败的情况 return; } // 1. 获取系统ANSI代码页ID const int ansiCodePage = CP_ACP; // 2. 计算所需宽字符缓冲区大小,转换ANSI字符串为宽字符数组 int wideCharLen = MultiByteToWideChar(ansiCodePage, 0, title, r, nullptr, 0); if (wideCharLen == 0) { // 处理转换错误 return; } wchar_t* wideBuffer = new wchar_t[wideCharLen + 1]; MultiByteToWideChar(ansiCodePage, 0, title, r, wideBuffer, wideCharLen); wideBuffer[wideCharLen] = L'\0'; // 3. 计算所需UTF-8缓冲区大小,转换宽字符为UTF-8数组 int utf8Len = WideCharToMultiByte(CP_UTF8, 0, wideBuffer, wideCharLen, nullptr, 0, nullptr, nullptr); if (utf8Len == 0) { delete[] wideBuffer; // 处理转换错误 return; } CHAR* utf8Buffer = new CHAR[utf8Len + 1]; WideCharToMultiByte(CP_UTF8, 0, wideBuffer, wideCharLen, utf8Buffer, utf8Len, nullptr, nullptr); utf8Buffer[utf8Len] = '\0'; // 4. 构造UTF-8编码的std::string std::string windowTitle(utf8Buffer); // 清理动态分配的内存 delete[] wideBuffer; delete[] utf8Buffer; // 此时s1与s2的Base64编码应一致 std::string str = "Pesquisa de domínio GoDaddy - Brave"; auto s1 = QByteArray::fromStdString(windowTitle).toBase64(); auto s2 = QByteArray::fromStdString(str).toBase64();
说明
- 代码中使用了
MultiByteToWideChar和WideCharToMultiByte两个Windows API完成编码转换,全程使用原生字符数组,未依赖wstring或GetWindowTextW。 - 转换后的
windowTitle是UTF-8编码,与源码中直接定义的字符串编码一致,因此两者的Base64编码结果会完全相同。
内容的提问来源于stack exchange,提问作者Laila
相关产品推荐
相关产品推荐

