I am trying to convert a program for multibyte character to Unicode.
I have gone through the program and preceded the string literals with L so they look like L"string".
This has worked but I am now left with a C style string that won't conform. I have tried the L and putting it in TEXT() but the L gets added to the variable name -- not the string -- if I use TEXT().
I have tried making it a TCHAR but then it complains that it cannot convert a TCHAR to a char *.
What options am I left with?
I know C and C++ are different. It is an old in-house C library that has been used in C++ projects for several years now.
The LPWSTR type is a 32-bit pointer to a string of 16-bit Unicode characters, which MAY be null-terminated. The LPWSTR type specifies a pointer to a sequence of Unicode characters, which MAY be terminated by a null character (usually referred to as "null-terminated Unicode").
The std::mbstowcs function is what you are looking for:
char text[] = "something"; wchar_t wtext[20]; mbstowcs(wtext, text, strlen(text)+1);//Plus null LPWSTR ptr = wtext; for strings,
string text = "something"; wchar_t wtext[20]; mbstowcs(wtext, text.c_str(), text.length());//includes null LPWSTR ptr = wtext; --> ED: The "L" prefix only works on string literals, not variables. <--
The clean way to use mbstowcs is to call it twice to find the length of the result:
const char * cs = <your input char*> size_t wn = mbsrtowcs(NULL, &cs, 0, NULL); // error if wn == size_t(-1) wchar_t * buf = new wchar_t[wn + 1](); // value-initialize to 0 (see below) wn = mbsrtowcs(buf, &cs, wn + 1, NULL); // error if wn == size_t(-1) assert(cs == NULL); // successful conversion // result now in buf, return e.g. as std::wstring delete[] buf; Don't forget to call setlocale(LC_CTYPE, ""); at the beginning of your program!
The advantage over the Windows MultiByteToWideChar is that this is entirely standard C, although on Windows you might prefer the Windows API function anyway.
I usually wrap this method, along with the opposite one, in two conversion functions string->wstring and wstring->string. If you also add trivial overloads string->string and wstring->wstring, you can easily write code that compiles with the Winapi TCHAR typedef in any setting.
[Edit:] I added zero-initialization to buf, in case you plan to use the C array directly. I would usually return the result as std::wstring(buf, wn), though, but do beware if you plan on using C-style null-terminated arrays.[/]
In a multithreaded environment you should pass a thread-local conversion state to the function as its final (currently invisible) parameter.
Here is a small rant of mine on this topic.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With