NOTE: This class is no longer maintained by me. I later created a tstring class, which you can find here.

This is a tutorial on how to use my twStringStuff class and supporting functions. UNICODE is a pain in the butt, but at least this will make things easier for you. I hope it's pretty intuitive. You can download the twStringStuff class here. The class is designed for C++ string and wstring, and to help convert between the two. I went ahead and defined functions for tcout and tcin.

There were very clever STL algorithms out there, but I wasn't completely sure that they were able to convert between multibyte strings and UNICODE strings without data loss. So, I made this. As you might have noticed, I like grouping similar functions into a class.

In twStringStuff.h:

typedef basic_string<TCHAR> tstring; // So that I have an STL string that's set to the program settings

#ifdef _UNICODE
   #define tcout wcout
   #define tcin  wcin
#else
   #define tcout cout
   #define tcin  cin
#endif

class twStringStuff
{
public:
   // convert the other string type to char* and wchar_t *. Don't need it for the same string
   // because it already has a function to do that (c_str())!
   size_t wstring2charstring(char *dest, wstring source);
   size_t string2wchartstring(wchar_t *dest, string source);

   // Take the char* and wchar_t* strings and put them into the opposite string thing
   string  wchar_t_string2string(wchar_t *source);
   wstring charString2wstring(char *source);

   // convert the string types using C methods. Returns the result of the conversion
   string  wstring2string(wstring str);
   wstring string2wstring(string str);


   // make it easier to convert to/from tstrings.
   string  GimmeString (tstring str);  // give it a tstring, and it returns the string version
   wstring GimmeWString(tstring str);  // give it a tstring, and it returns the wide string version

   tstring to_tstring(string str);      // take the string or wstring, and returns the tstring version
   tstring to_tstring(wstring str);

   // and take the char* / wchar_t * strings and convert them to a tstring
   tstring to_tstring(char    *str);
   tstring to_tstring(wchar_t *str);

   // and convert them back
   size_t tstring2charString   (char *dest,    tstring source);
   size_t tstring2wchar_tString(wchar_t *dest, tstring source);

   // I realized that I should have TCHAR <-> wchar and char functions as well
   // that aren't already implemented above
   size_t tcharString2charString   (char    *dest, TCHAR *source);
   size_t tcharString2wchar_tString(wchar_t *dest, TCHAR *source);

   // Convert TCHAR * to char/wchar_t
   size_t charString2tcharString   (TCHAR *dest, char    *source);
   size_t wchar_tstrint2tcharstring(TCHAR *dest, wchar_t *source);
};

Example code:

#include <iostream>

 using std::cout;
 using std::wcout; // UNICODE cout command
 using std::endl;
#include <string>
 using std::string;
 using std::wstring;

#include "twStringStuff.h"

int main()
{
   string str   = "Hiya!";
   wstring wstr = L"Meow!";
   tstring tstr = TEXT("Freedom!");

   char    cstr []  = "Fred";
   wchar_t wcstr [] = L"Wilma";
   TCHAR   tcstr []  = TEXT("Barney");

   char    cstr2  [20];
   wchar_t wcstr2 [20];
   TCHAR   tcstr2 [20];

   string str2;
   wstring wstr2;
   tstring tstr2;
   tstring tstr3;

   twStringStuff twss;

   tcout << TEXT("convert str to UNICODE") << endl;

   wstr2 = twss.string2wstring(str);
   wcout << wstr2 << endl;

   tcout << TEXT("convert it back to Multibyte") << endl;

   str2 = twss.wstring2string(wstr2);
   cout << str2 << endl;

   tcout << TEXT("convert wstring to Multibyte") << endl;
  
   str2 = twss.wstring2string(wstr);
   cout << str2 << endl;

   // Now use the #defined tcout to display. Note that I #defined tcout and tendl in twStringStuff.h
   tcout << tstr << endl;

   tcout << TEXT("tstring converted to multibyte and UNICODE") << endl;  

   // give me a multibyte string regardless of what the program is set to
   str2 = twss.GimmeString(tstr);
  
   // and give me the UNICODE version as well
   wstr2 = twss.GimmeWString(tstr);

   // check the results
   cout  << str2  << endl;
   wcout << wstr2 << endl;

   tcout << TEXT("Test for cin.") << endl;  

   tcout << "Please enter a word: ";
   tcin >> tstr2;

   tcout << TEXT("Convert it to a multibyte string.") << endl;
   str2 = twss.GimmeString(tstr2);
   cout << str2 << endl;

   tcout << TEXT("Convert it to a UNICODE string.") << endl;

   wstr2 = twss.GimmeWString(tstr2);
   wcout << wstr2 << endl; // and whew. Keeping track of 3 different cout statements at 1:22 AM is tricky

   // Convert it to a tstring. Since it's overloaded to take both types, you use the same function name

   tcout << TEXT("Convert stuff to a tstring.") << endl;

   tstr2 = twss.to_tstring(str2);
   tstr3 = twss.to_tstring(wstr); // note that this is the predefined string above

   tcout << tstr2 << endl;
   tcout << tstr3 << endl;

   tcout << TEXT("Convert between char and wchar_t arrays to strings") << endl;

   str2  = twss.wchar_t_string2string(wcstr);
   wstr2 = twss.charString2wstring(cstr);

   cout  << str2 << endl;
   wcout << wstr2 << endl;

   // and the other way. Convert UNICODE strings to a C char array
   // and convert the multibyte string to wchar_t array
   twss.wstring2charstring(cstr2, wstr);
   twss.string2wchartstring(wcstr2, str);

   tcout << TEXT("Converted UNICODE string to C char array / multibyte string to wchar_t.") << endl;

   cout  << cstr2 << endl;
   wcout << wcstr2 << endl;

   // now repeat with tstrings
   tstr2 = twss.to_tstring(cstr);
   tstr3 = twss.to_tstring(wcstr);

   tcout << TEXT("Converted from cstr and wcstr to tstrings.") << endl;
   tcout << tstr2 << endl;
   tcout << tstr3 << endl;

   tcout << TEXT("Converted tstrings to cstr and wcstr") << endl;
   twss.tstring2charString(cstr2, tstr);
   twss.tstring2wchar_tString(wcstr2, tstr);

   cout << cstr2 << endl;
   wcout << wcstr2 << endl;

   tcout << TEXT("Convert from TCHAR [] to char[]/wchar_t []") << endl;
   twss.tcharString2charString(cstr2, tcstr);
   twss.tcharString2wchar_tString(wcstr2, tcstr);

   cout << cstr2 << endl;
   wcout << wcstr2 << endl;

   tcout << TEXT("Convert from char[]/wchar_t to TCHAR []") << endl;
   twss.charString2tcharString(tcstr2, cstr);
   tcout << tcstr2 << endl;

   twss.wchar_tstrint2tcharstring(tcstr2, wcstr);
   tcout << tcstr2 << endl;

   // simply an easy way to see the results using the VS debugger
   system("pause");

   return 42;
}
/*
Output:

convert str to UNICODE
Hiya!
convert it back to Multibyte
Hiya!
convert wstring to Multibyte
Meow!
Freedom!
tstring converted to multibyte and UNICODE
Freedom!
Freedom!
Test for cin.
Please enter a word: c0w
Convert it to a multibyte string.
c0w
Convert it to a UNICODE string.
c0w
Convert stuff to a tstring.
c0w
Meow!
Convert between char and wchar_t arrays to strings
Wilma
Fred
Converted UNICODE string to C char array / multibyte string to wchar_t.
Meow!
Hiya!
Converted from cstr and wcstr to tstrings.
Fred
Wilma
Converted tstrings to cstr and wcstr
Freedom!
Freedom!
Convert from TCHAR [] to char[]/wchar_t []
Barney
Barney
Convert from char[]/wchar_t to TCHAR []
Fred
Wilma
Press any key to continue . . .
*/


The outputs between Multibyte builds and UNICODE builds should be the same.

Copyright 2010 (c) by Joe Plante
You are free to use this code for any project, but if you mention authors in your program or textbook, please give me a note/special thanks.