0
votes

I am trying to send text packets over the network using winsock. However the text is stored as wchar_t and I need to be able to convert the text into byte (char) format for sending over the network, which will then be converted back to wchar_t.

I've experimented with using ostringstream and have converted the wchar_t string of mine to what looks like byte format, however when I try to go the reverse I get a load of gibberish.

I can't seem to find any answers whilst looking online, so any help would be much appreciated.

OK here is some code that I played with.

std::wstring text( ieS("Hello") );
std::ostringstream ostr;
ostr.imbue( std::locale( ) );
ostr << text.c_str();
std::string text2 = ostr.str();

Convert to std::string to get char format.

std::wostringstream wostr;
wostr.imbue( std::locale( ) );
wostr << text2.c_str();
text = oss.str(); // gibberish

Convert back to std::wstring to get wchar_t format...

2
You need to take a closer look on how Unicode is represented - it sounds as if you have some assumptions about length etc. When bytes arrive you need provide enough information to know how to decode the bytes into a Unicode character.AndersK
You should probably use UTF-8 when things are going over the network in any case.Billy ONeal
Billy: Why? I'm actually confused as to why Sent1nel thinks they need to convert to an 8 bit character set before transmitting on the wire - winsock doesn't care what's in the payload, so the unicode characters will transmit just fine.ReinstateMonica Larry Osterman
@Larry Osterman : Basically the same reason as why you use htons or htonl - you shouldn't hardcode assumptions about the other side. There are two endian variants of UTF-16, so you should make an explicit choice there, but UTF-8 is endian-neutral and simply avoids the need for such a choice.MSalters

2 Answers

1
votes

Your friends here are:

WideCharToMultiByte, passing the code page for UTF-8 as the MB code page.

MultiByteToWideChar, ditto.

0
votes

Example reposted from here:

#include <locale>
#include <iostream>
#include <string>
#include <sstream>
using namespace std ;

wstring widen( const string& str )
{
    wostringstream wstm ;
    const ctype<wchar_t>& ctfacet = 
                        use_facet< ctype<wchar_t> >( wstm.getloc() ) ;
    for( size_t i=0 ; i<str.size() ; ++i ) 
              wstm << ctfacet.widen( str[i] ) ;
    return wstm.str() ;
}

string narrow( const wstring& str )
{
    ostringstream stm ;
    const ctype<char>& ctfacet = 
                         use_facet< ctype<char> >( stm.getloc() ) ;
    for( size_t i=0 ; i<str.size() ; ++i ) 
                  stm << ctfacet.narrow( str[i], 0 ) ;
    return stm.str() ;
}

int main()
{
  {
    const char* cstr = "abcdefghijkl" ;
    const wchar_t* wcstr = widen(cstr).c_str() ;
    wcout << wcstr << L'\n' ;
  }
  {  
    const wchar_t* wcstr = L"mnopqrstuvwx" ;
    const char* cstr = narrow(wcstr).c_str() ;
    cout << cstr << '\n' ;
  } 
}