C++: socket encoding (working with TeamSpeak) -


as i'm working on program teamspeak server, need retrieve names of online users i'm doing sockets - that's working fine far.
in ui i'm displaying clients in listbox working. nevertheless i'm having problems wrong displayed characters , symbols in listbox. i'm using following code:

//... auto getclientlist() -> void{     = 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); } //... 

i've checked lastlog, temporary , users[i] (by writing them file), of them have no encoding problem characters or symbols (for example andrè). if add string directly:
sendmessage(hwnd_2, lb_addstring, (wparam)null, (lparam)(lptstr)l"andrè", displayed correctly in listbox.
what might issue here, problem code or else?


update 1:
i continued working on problem , considered word olè! receiving socket. result got, following:
o (79) | l (108) | � (-61) | � (-88) | ! (33).
how can convert char array wstring containing correct characters?


solution:
@isanae mentioned in post, std::wstring_convert-template did trick me, thank much!

many things can go wrong in code, , don't show of it. what's particularly lacking definition of variables.

assuming users[i] contains meaningful data, don't how encoded. ascii? utf-8? utf-16? fact can output file , read editor doesn't mean anything, editors able guess @ encoding.

if utf-16 (the native encoding on windows), see no reason code not work. 1 way check break debugger , @ individual bytes in users[i]. if see every character value less 128 followed 0, it's utf-16.

if not utf-16, you'll need convert it. there variety of ways this, multibytetowidechar may easiest. make sure set codepage same encoding used sender. may cp_utf8, or actual codepage.

note hardcoding string non-ascii characters doesn't either, you'd first have find out encoding of file itself. know versions of visual c++ convert source file utf-16 if encounters non-ascii characters, may happened you.

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

how can convert char array wstring containing correct characters?

this utf-8 string. has converted utf-16 windows can use it.

this portable, c++11 solution on implementations sizeof(wchar_t) == 2. if not case, char16_t , std::u16string may used, recent version of visual c++ of writing (2015 rc) doesn't implement std::codecvt char16_t , char32_t.

#include <string> #include <codecvt>  std::wstring utf8_to_utf16(const std::string& s) {     static_assert(sizeof(wchar_t)==2, "wchar_t needs 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 2 bytes");     std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> conv;     return conv.to_bytes(s); } 

windows-only:

#include <string> #include <cassert> #include <memory> #include <codecvt> #include <windows.h>  std::wstring utf8_to_utf16(const std::string& s) {     // getting required size in characters (not bytes) of     // 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 buffer enough characters in     std::unique_ptr<wchar_t[]> buffer(new wchar_t[size]);      // converting utf8 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 required size in bytes of 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 buffer enough characters in     std::unique_ptr<char[]> buffer(new char[size]);      // converting utf16 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); } 

test:

// utf-8 string const std::string s = {79, 108, -61, -88, 33};  ::messageboxw(0, utf8_to_utf16(s).c_str(), l"", mb_ok);  

Comments

Popular posts from this blog

python - TypeError: start must be a integer -

c# - DevExpress RepositoryItemComboBox BackColor property ignored -

django - Creating multiple model instances in DRF3 -