I'm looking for a method, or a code snippet for converting std::string to LPCWSTR
-
Note, there is a now-deleted answer by OP that indicated the solution they used came from an MSDN article, [*Convert std::string to LPCWSTR (best way in c++*)](https://web.archive.org/web/20210506154303/https://social.msdn.microsoft.com/Forums/en-US/0f749fd8-8a43-4580-b54b-fbf964d68375/convert-stdstring-to-lpcwstr-best-way-in-c?forum=Vsexpressvc#f59dfd52-580d-43a7-849f-9519d858a8e9). – TylerH Jan 10 '22 at 15:01
6 Answers
The solution is actually a lot easier than any of the other suggestions:
std::wstring stemp = std::wstring(s.begin(), s.end());
LPCWSTR sw = stemp.c_str();
Best of all, it's platform independent.

- 4,207
- 11
- 50
- 75

- 1,737
- 1
- 10
- 2
-
46This only works if all the characters are single byte, i.e. ASCII or [ISO-8859-1](http://en.wikipedia.org/wiki/ISO-8859-1). Anything multi-byte will fail miserably, including UTF-8. – Mark Ransom Sep 03 '13 at 16:20
-
I believe you can simplify the first line to: std::wstring stemp( s.begin(), s.end() ); That would eliminate a possible copy and look simpler; note that the compiler _might_ eliminate the copy anyhow, but this is still a simpler look. – Kit10 Mar 09 '16 at 20:38
-
25Lord, what's with all the upvotes? This answer works, **sometimes**, by coincidence alone. It completely ignores character **encodings**. You cannot simply widen a narrow character, and hope for it to magically turn into a wide character representing the same code point. It is the moral equivalent of a `reinterpret_cast`. **This code does not work. Do not use.**. – IInspectable Jun 30 '16 at 09:49
-
4@nik: On Windows, a `char` is usually encoded as ANSI. With ANSI encoding, the values 128 through 255 are interpreted using the currently active code page. Shoving those values into a `wchar_t` (UTF-16 encoding on Windows) will not produce the desired result. If you want to be precise, this works in exactly 50% of the cases. Taking DBCS character encoding into account, that percentage further decreases. – IInspectable Oct 20 '18 at 18:31
-
It looks working fine if you have _initially_ `wstring`, for example: `std::wstring szTitle = L"Hello — こんにちは — 你好!— ";` is correctly displayed in a window title bar, when I pass `szTitle.c_str()` to a WinAPI function. However the issue is about if you have initially `string`. – KeyKi Jan 22 '22 at 06:34
If you are in an ATL/MFC environment, You can use the ATL conversion macro:
#include <atlbase.h>
#include <atlconv.h>
. . .
string myStr("My string");
CA2W unicodeStr(myStr);
You can then use unicodeStr as an LPCWSTR. The memory for the unicode string is created on the stack and released then the destructor for unicodeStr executes.

- 27,121
- 13
- 66
- 85
I prefer using standard converters:
#include <codecvt>
std::string s = "Hi";
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
std::wstring wide = converter.from_bytes(s);
LPCWSTR result = wide.c_str();
Please find more details in this answer: https://stackoverflow.com/a/18597384/592651
Update 12/21/2020 : My answer was commented on by @Andreas H . I thought his comment is valuable, so I updated my answer accordingly:
codecvt_utf8_utf16
is deprecated in C++17.- Also the code implies that source encoding is UTF-8 which it usually isn't.
- In C++20 there is a separate type std::u8string for UTF-8 because of that.
But it worked for me because I am still using an old version of C++ and it happened that my source encoding was UTF-8 .

- 806
- 1
- 11
- 22
-
2Unfortunately `codecvt_utf8_utf16` is deprecated in C++17. Also you imply your source encoding is UTF-8 which it usually isnt. In C++20 there is the separate type `std::u8string` for UTF-8 because of that. – Andreas H. Oct 26 '20 at 08:35
- After knowing that, the C++11-standard has rules for
.c_str()
method (maybe.data()
too), which allows us to useconst_cast
,
(I mean, normally using
const_cast
may be dangerous)
- we can safely take "
const
" input parameter. - Then finally, use "
const_cast
" instead of any unnecessary allocation and deletion.
std::wstring s2ws(const std::string &s, bool isUtf8 = true)
{
int len;
int slength = (int)s.length() + 1;
len = MultiByteToWideChar(isUtf8 ? CP_UTF8 : CP_ACP, 0, s.c_str(), slength, 0, 0);
std::wstring buf;
buf.resize(len);
MultiByteToWideChar(isUtf8 ? CP_UTF8 : CP_ACP, 0, s.c_str(), slength,
const_cast<wchar_t *>(buf.c_str()), len);
return buf;
}
std::wstring wrapper = s2ws(u8"My UTF8 string!");
LPCWSTR result = wrapper.c_str();
Note that we should use
CP_UTF8
for C++'s string-literal, but in some cases you may need to instead useCP_ACP
(by setting second parameter tofalse
).

- 7,611
- 5
- 39
- 71
-
nice, but it seems that there will be problems when processing some characters, like `Microsoft® LifeCam Studio(TM)`. – Jay Nov 04 '21 at 13:17
-
1@Jay Probably it's related to encoding; I tested your sample "®" with Qt's `QString::fromWCharArray(...)` method and the result was "`®`" but **`QString::fromAscii(...)` works fine, so it's ASCII** – Top-Master Nov 04 '21 at 14:17
-
If you want to convert `"My UTF8 string!"`, you should be using `CP_UTF8`. As currently implemented, this uses [the system default Windows ANSI code page](https://learn.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-multibytetowidechar). Also, C++' string has a [`data()`](https://en.cppreference.com/w/cpp/string/basic_string/data) member so that you don't have to `const_cast`. – IInspectable Jan 10 '22 at 19:47
-
@IInspectable Both `.c_str()` and `.data()` are `const` (while `MultiByteToWideChar` does NOT take `const` input, at least in my SDK, so need to simply cast or allocate new buffer). But thanks for mentioning `CP_UTF8`, see my edit ;-) – Top-Master Jan 11 '22 at 08:10
-
-
The more common method for pre-C++17 code would be `&buf[0]` rather than `c_str()` with a `const_cast`. As for ordinary C++ string literals, they use the execution character set encoding, which may or may not be UTF-8. If you want to force UTF-8 encoding you need to use the `u8` prefix (see [string literal](https://en.cppreference.com/w/cpp/language/string_literal)), and deal with breaking changes introduced in C++20. – IInspectable Jan 11 '22 at 09:32
-
@IInspectable above's first parameter is `const` (so anything without `const_cast` causes compile error, and I am specifically using `c_str` method, because of nice C++-standard rules allowing that). And thanks for reminding execution encoding, please feel free to solve related question: [How to convert execution character set string to a UTF-8 string?](https://stackoverflow.com/q/51041467/8740349) – Top-Master Jan 11 '22 at 17:33
If you are using QT then you can convert to QString and then myqstring.toStdWString() will do the trick.

- 11
- 1
It's so easy, no need to apply any custom method. Try with this:
string s = "So Easy Bro"
LPCWSTR wide_string;
wide_string = CA2T(s.c_str());
I think, it will works.

- 9
- 2
-
2This is using a library (MFC or ATL). And it's using the wrong conversion macro (should be `CA2W`). But if you're using MFC or ATL already, then you can construct a `CStringW` from a pointer to `char*`, without introducing a pointer whose ownership is unclear, or using conversion macros that are hard to understand. – IInspectable Jan 10 '22 at 14:48