Thursday, September 15, 2016

Conversion Between std::string and std::wstring

Go to Index

While developing my brand new (being over a year old at least...) framework I decided I want to use ANSI chars (std::string or char) as often as possible, instead of more complex encodings like Unicode (stored in std::wstring or wchar_t). As file names for instance. And for tons of other stuff. However, many functions, most notably from Windows SDK, expect wide chars instead of pure chars. This is the case with D3DCompileFromFile function that I used. My custom function called CompileShaderFromFile calls this function but takes as input file name to a shader file stored in std::string, which cannot be passed to D3DCompileFromFile. At least not without conversion. So I started to search Google for conversion functions between the two, chars and wide chars. To my surprise I found a lot of code that did not work straight away, was very complex or was platform-specific. Eventually, I thought that since built-in STL library is so packed with various conversion functions then maybe there is something to convert between string and wstring. Turns out there is. You can add a wchar_t to string and a char to wstring, and the append function (+= operator in my code) will perform proper conversion.
Here goes the code:
inline wstring StringToWString(const string& s)
{
    wstring temp = L"";

    for (uint i = 0; i < s.length(); i++)
        temp += (wchar_t)s[i];

    return temp;
}

inline string WStringToString(const wstring& s)
{
    string temp = "";

    for (uint i = 0; i < s.length(); i++)
        temp += (char)s[i];

    return temp;
}
Or equivalently:
inline wstring StringToWString(const string& s)
{
    return wstring(s.begin(), s.end());
}

inline string WStringToString(const wstring& s)
{
    return string(s.begin(), s.end());
}
And that's it. With these two functions (or actually only the first one) I was able to pass string to all my custom functions and convert it to wstring when necessary. Simple, clean and elegant solution.

IMPORTANT EDIT (17.09.2016):

In a GameDev.net thread (http://www.gamedev.net/topic/682185-conversion-between-stdstring-and-stdwstring/) it was pointed out to me that the code above will only work for ISO-8859-1 encoding and that I'm actually not converting chars and wide chars but simply cast them. This is fine for the just-mentioned encoding but might cause troubles in others.

Anyway, my problem has been solved with this simple solution so if you don't have funky chars in your paths and just want to pass wide chars which you know are ANSI (and stored in chars) then casting chars to wide chars will do the trick.