Page 1 of 1

Converting from wchar_t* to char* from Irrlicht's EditBox

Posted: Tue Oct 20, 2009 6:16 pm
by Weng
I am trying to display and use the text which is input into an EditBox. The text has to be converted from a wchar_t* to a char* in order to be used.

What I did is this:

const wchar_t* startIndex = editBox1->getText();

char* start = new char[wcslen(startIndex) + 1];
cout<<wcslen(startIndex)<<endl;

wcstombs( start, startIndex, wcslen(startIndex));

cout<<start<<endl;

When I typed the number "2" into the edit box, the code returned 2=zzzz||. The same happened when I entered "77". (the result was 77=zzzz|)

I printed out the results of wcslen and the length returned by the function is correct. However, the end result contains some garbage characters after the input character.

How do I convert from wchar_t* to char* ?

Posted: Tue Oct 20, 2009 6:37 pm
by Murloc992
This may come useful:

Code: Select all

irr::core::stringw make_wide (const irr::core::string& s)
{
  return irr::core::stringw (s);
}

irr::core::stringc make_narrow (const irr::core::stringw& w)
{
  return irr::core::stringc (w);
}

std::stringw make_std (const irr::core::stringw& w)
{
  return std::wstring (w.c_str(), w.size());
}

std::string make_std (const irr::core::stringc& s)
{
  return std::string (s.c_str(), s.size());
}

irr::core::stringc make_irr (const std::string& s)
{
  return irr::core::stringc (s.c_str(), s.size());
}

irr::core::stringw make_irr (const std::wstring& w)
{
  return irr::core::stringw (w.c_str(), w.size());
} 

Posted: Tue Oct 20, 2009 6:37 pm
by RodrigoAmazonas
I've got a similar problem, hope these two functions may help you. By the way, I still didn't test to see if there's a memory leak in the first one.

Code: Select all

const wchar_t *str2wchar_t(string str)
{
    // null-call to get the size
    size_t needed = ::mbstowcs(NULL,&str[0],str.length());
    // allocate
    wstring output;          // MEMORY LEAK? probably
    output.resize(needed);
    // real call
    ::mbstowcs(&output[0],&str[0],str.length());
    // You asked for a pointer
    const wchar_t *pout = output.c_str();
    return pout;
}

string wchar_t2str(const wchar_t* str)
{
    string s;
    int i = 0;
    while (str[i] != 0)
    {
        s += str[i];
        i++;
    }
    return s;
}

Posted: Tue Oct 20, 2009 6:43 pm
by cwick
You have a buffer underrun bug. You need to pass wcstombs the actual size, in bytes, of the output buffer, not the length of the input string.

Also, you are incorrectly allocating the new multi-byte buffer. In general, you can't determine the number of bytes required to convert a sequence of wide characters to a corresponding sequence of multi-byte characters. So, you have two options: you can either plan for the worst case and just allocate a buffer that is twice the length of the input string, (plus one for the null terminator) or call wcstombs with NULL as the first parameter, and it will return you the number of bytes required for your output buffer (again, not including null-terminator).

Posted: Tue Oct 20, 2009 7:28 pm
by ArakisTheKitsune
Here is a very simple and efective solution: instead of char* use irr::core::stringc

Code: Select all

const wchar_t* startIndex = editBox1->getText();
irr::core::stringc start = stringc(startIndex);
And it's recommended to use irr::core::stringw instead of wchar_t*
http://irrlicht.sourceforge.net/docu/cl ... tring.html here you have explanation about irr::core::string template class