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 string
s,
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