gpt4 book ai didi

C++:套接字编码(使用 TeamSpeak)

转载 作者:行者123 更新时间:2023-11-28 00:15:29 27 4
gpt4 key购买 nike

由于我目前正在为 TeamSpeak 服务器开发一个程序,我需要检索当前在线用户的名称,我正在使用套接字进行这些操作 - 到目前为止工作正常。
在我的 UI 中,我'在基本上工作的 ListBox 中显示所有客户端。尽管如此,我还是遇到了 ListBox 中错误显示的字符和符号的问题。我正在使用以下代码:

//...
auto getClientList() -> void{
i = 0;
queryString.str("");
queryString.clear();
queryString << clientlist << " \n";
send(sock, queryString.str().c_str(), strlen(queryString.str().c_str()), NULL);
TeamSpeak::getAnswer(1);
while(p_1 != -1){
p_1 = lastLog.find(L"client_nickname=", sPos + 1);
if(p_1 != -1){
sPos = p_1;
p_2 = lastLog.find(L" ", p_1);
temporary = lastLog.substr(p_1 + 16, p_2 - (p_1 + 16));
users[i].assign(temporary.begin(), temporary.end());
SendMessage(hwnd_2, LB_ADDSTRING, (WPARAM)NULL, (LPARAM)(LPTSTR)(users[i].c_str()));
i++;
}
else{
sPos = 0;
p_1 = 0;
break;
}
}
TeamSpeak::getAnswer(0);
}
//...

我已经检查了 lastLogtemporaryusers[i](通过将它们写入文件),但是所有这些没有字符或符号的编码问题(例如 Andrè)。如果我直接添加一个字符串:
SendMessage(hwnd_2, LB_ADDSTRING, (WPARAM)NULL, (LPARAM)(LPTSTR)L"Andrè",它会在列表框中正确显示。
这里可能有什么问题,是我的代码有问题还是其他什么?


更新 1:
我最近继续研究这个问题并考虑从套接字接收单词 Olè!。我得到的结果如下:
O (79) |我 (108) | � (-61) | � (-88) | ! (33).
如何将这个 char 数组 转换为包含正确字符的 wstring


解决方案:
正如@isanae 在他的帖子中提到的,std::wstring_convert 模板为我解决了问题,非常感谢!

最佳答案

这段代码中有很多地方可能出错,而您并没有展示太多。特别缺乏的是所有这些变量的定义。

假设 users[i] 包含有意义的数据,您也不说明它是如何编码的。它是 ASCII 码吗? UTF-8? UTF-16?您可以将其输出到文件并使用编辑器读取它这一事实并不意味着什么,因为大多数编辑器都能够猜测编码。

如果它真的是 UTF-16(Windows 上的 native 编码),那么我认为没有理由让这段代码不起作用。一种检查方法是进入调试器并查看 users[i] 中的各个字节。如果您看到每个值小于 128 的字符后跟一个 0,那么它可能是 UTF-16。

如果它不是 UTF-16,则需要对其进行转换。有多种方法可以做到这一点,但是 MultiByteToWideChar可能是最简单的。确保将 codepage 设置为与发件人使用的编码相同。它可能是 CP_UTF8,或 actual codepage .

另请注意,使用非 ASCII 字符对字符串进行硬编码也无济于事,因为您首先必须找出文件本身的编码。我知道如果遇到非 ASCII 字符,某些版本的 Visual C++ 会将您的源文件转换为 UTF-16,这可能是您遇到的情况。

O (79) | l (108) | � (-61) | � (-88) | ! (33).

How can I convert this char array to a wstring containing the correct characters?

这是一个 UTF-8 字符串。它必须转换为 UTF-16 以便 Windows 可以使用它。

这是一个可移植的 C++11 解决方案,实现了 sizeof(wchar_t) == 2。如果不是这种情况,则可以使用 char16_tstd::u16string,但在撰写本文时最新版本的 Visual C++ (2015 RC) 没有为 char16_tchar32_t 实现 std::codecvt

#include <string>
#include <codecvt>

std::wstring utf8_to_utf16(const std::string& s)
{
static_assert(sizeof(wchar_t)==2, "wchar_t needs to be 2 bytes");
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> conv;
return conv.from_bytes(s);
}

std::string utf16_to_utf8(const std::wstring& s)
{
static_assert(sizeof(wchar_t)==2, "wchar_t needs to be 2 bytes");
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> conv;
return conv.to_bytes(s);
}

仅限 Windows:

#include <string>
#include <cassert>
#include <memory>
#include <codecvt>
#include <Windows.h>

std::wstring utf8_to_utf16(const std::string& s)
{
// getting the required size in characters (not bytes) of the
// output buffer
const int size = ::MultiByteToWideChar(
CP_UTF8, 0, s.c_str(), static_cast<int>(s.size()),
nullptr, 0);

// error handling
assert(size != 0);

// creating a buffer with enough characters in it
std::unique_ptr<wchar_t[]> buffer(new wchar_t[size]);

// converting from utf8 to utf16
const int written = ::MultiByteToWideChar(
CP_UTF8, 0, s.c_str(), static_cast<int>(s.size()),
buffer.get(), size);

// error handling
assert(written != 0);

return std::wstring(buffer.get(), buffer.get() + written);
}

std::string utf16_to_utf8(const std::wstring& ws)
{
// getting the required size in bytes of the output buffer
const int size = ::WideCharToMultiByte(
CP_UTF8, 0, ws.c_str(), static_cast<int>(ws.size()),
nullptr, 0, nullptr, nullptr);

// error handling
assert(size != 0);

// creating a buffer with enough characters in it
std::unique_ptr<char[]> buffer(new char[size]);

// converting from utf16 to utf8
const int written = ::WideCharToMultiByte(
CP_UTF8, 0, ws.c_str(), static_cast<int>(ws.size()),
buffer.get(), size, nullptr, nullptr);

// error handling
assert(written != 0);

return std::string(buffer.get(), buffer.get() + written);
}

测试:

// utf-8 string
const std::string s = {79, 108, -61, -88, 33};

::MessageBoxW(0, utf8_to_utf16(s).c_str(), L"", MB_OK);

关于C++:套接字编码(使用 TeamSpeak),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30606838/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com