我正在为TS3客户端编写插件,但是遇到了问题...
其中一个频道名称带有一个特殊符号(╠),这是我认为是扩展的ascii表中的一个特殊字符。
在将其记录为INSIDE teampeak时,该字符显示正常,但是当尝试使用其C接口将其复制到Windows剪贴板时,它将返回一个完全不同的字符(â)。
在我阅读到扩展的ascii表使用的字节数比常规char占用的字节更多时,我尝试将其转换为WCHAR,但这也不起作用。
我使用以下代码将char *复制到剪贴板中,该剪贴板在某个地方找到,并使用使用WCHAR的其他代码进行了更改:
void SaveClipboard(char* tx)
{
WCHAR text[140];
swprintf(text, 140, L"%hs", tx);
if(OpenClipboard(NULL))
{
EmptyClipboard();
HGLOBAL global = GlobalAlloc(GMEM_DDESHARE, 2 * (wcslen(text) + 1)); //text size + \0 character
WCHAR* pchData;
pchData = (WCHAR*)GlobalLock(global);
wcscpy(pchData, text);
GlobalUnlock(pchData);
SetClipboardData(CF_UNICODETEXT, global);
CloseClipboard();
}
}
答案 0 :(得分:4)
wchar_t
是UTF-16
编码的,但是您获得的数据是UTF-8
编码的。您无需在这两种编码之间进行转换,只需重新解释字节即可。
看一下这些字符的代码点,应该很清楚正在发生的事情:╠
的UTF-8代码点是0xE2 0x95 0xA0
,而â
的UTF-16代码点是0x00 0xE2
,而╠
的UTF-16代码点是0x25 0x60
。
swprintf(text, 140, L"%hs", tx);
<-这仅将每个char
转换为wchar_t
,将3字节的UTF-8
代码点0xE2 0x95 0xA0
变成三个2字节的{{1 }}代码点:UTF-16
,0x00 0xE2
和0x00 0x95
。
要从0x00 0xA0
获取0x25 0x60
,您需要实际转换数据:
0xE2 0x95 0xA0
或者,由于您已经在使用WINAPI,因此可以使用MultiByteToWideChar
:
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>> converter;
std::wstring text = converter.from_bytes(tx);