You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 14:47:33