Hi
How can I convert a std::string
to LPCSTR
? Also, how can I convert a std::string
to LPWSTR
?
I am totally confused with these LPCSTR
LPSTR
LPWSTR
LPCWSTR
?
Are LPWSTR
and LPCWSTR
are the same?
Hi
How can I convert a std::string
to LPCSTR
? Also, how can I convert a std::string
to LPWSTR
?
I am totally confused with these LPCSTR
LPSTR
LPWSTR
LPCWSTR
?
Are LPWSTR
and LPCWSTR
are the same?
str.c_str() gives you a const char *, which is an LPCSTR (Long pointer to C String) -- means that it's a 32-bit pointer to a 0 terminated string of characters. W means wide string (each character is 2 bytes).
The conversion is simple:
std::string str; LPCSTR lpcstr = str.c_str();
Call c_str() to get a const char * (LPCSTR) from a std::string.
It's all in the name:
LPSTR - (long) pointer to string - char *
LPCSTR - (long) pointer to constant string - const char *
LPWSTR - (long) pointer to Unicode (wide) string - wchar_t *
LPCWSTR - (long) pointer to constant Unicode (wide) string - const wchar_t *
LPTSTR - (long) pointer to TCHAR (Unicode if UNICODE is defined, ANSI if not) string - TCHAR *
LPCTSTR - (long) pointer to constant TCHAR string - const TCHAR *
You can ignore the L (long) part of the names -- it's a holdover from 16-bit Windows.
These are Microsoft defined typedefs which correspond to:
LPCSTR: pointer to null terminated const string of char
LPSTR: pointer to null terminated char string of char
(often a buffer is passed and used as an 'output' param)
LPCWSTR: pointer to null terminated string of const wchar_t
LPWSTR: pointer to null terminated string of wchar_t
(often a buffer is passed and used as an 'output' param)
To "convert" a std::string
to a LPCSTR depends on the exact context but usually calling .c_str()
is sufficient.
This works.
void TakesString(LPCSTR param);
void f(const std::string& param)
{
TakesString(param.c_str());
}
Note that you shouldn't attempt to do something like this.
LPCSTR GetString()
{
std::string tmp("temporary");
return tmp.c_str();
}
The buffer returned by .c_str()
is owned by the std::string
instance and will only be valid until the string is next modified or destroyed.
To convert a std::string
to a LPWSTR
is more complicated. Wanting an LPWSTR
implies that you need a modifiable buffer and you also need to be sure that you understand what character encoding the std::string
is using. If the std::string
contains a string using the system default encoding (assuming windows, here), then you can find the length of the required wide character buffer and perform the transcoding using MultiByteToWideChar
(a Win32 API function).
e.g.
void f(const std:string& instr)
{
// Assumes std::string is encoded in the current Windows ANSI codepage
int bufferlen = ::MultiByteToWideChar(CP_ACP, 0, instr.c_str(), instr.size(), NULL, 0);
if (bufferlen == 0)
{
// Something went wrong. Perhaps, check GetLastError() and log.
return;
}
// Allocate new LPWSTR - must deallocate it later
LPWSTR widestr = new WCHAR[bufferlen + 1];
::MultiByteToWideChar(CP_ACP, 0, instr.c_str(), instr.size(), widestr, bufferlen);
// Ensure wide string is null terminated
widestr[bufferlen] = 0;
// Do something with widestr
delete[] widestr;
}
Converting is simple:
std::string myString;
LPCSTR lpMyString = myString.c_str();
One thing to be careful of here is that c_str does not return a copy of myString, but just a pointer to the character string that std::string wraps. If you want/need a copy you'll need to make one yourself using strcpy.
The easiest way to convert a std::string
to a LPWSTR
is in my opinion:
std::string
to a std::vector<wchar_t>
wchar_t
in the vector.std::vector<wchar_t>
has a templated ctor which will take two iterators, such as the std::string.begin()
and .end()
iterators. This will convert each char to a wchar_t
, though. That's only valid if the std::string
contains ASCII or Latin-1, due to the way Unicode values resemble Latin-1 values. If it contains CP1252 or characters from any other encoding, it's more complicated. You'll then need to convert the characters.
The MultiByteToWideChar
answer that Charles Bailey gave is the correct one. Because LPCWSTR
is just a typedef for const WCHAR*
, widestr
in the example code there can be used wherever a LPWSTR
is expected or where a LPCWSTR
is expected.
One minor tweak would be to use std::vector<WCHAR>
instead of a manually managed array:
// using vector, buffer is deallocated when function ends
std::vector<WCHAR> widestr(bufferlen + 1);
::MultiByteToWideChar(CP_ACP, 0, instr.c_str(), instr.size(), &widestr[0], bufferlen);
// Ensure wide string is null terminated
widestr[bufferlen] = 0;
// no need to delete; handled by vector
Also, if you need to work with wide strings to start with, you can use std::wstring
instead of std::string
. If you want to work with the Windows TCHAR
type, you can use std::basic_string<TCHAR>
. Converting from std::wstring
to LPCWSTR
or from std::basic_string<TCHAR>
to LPCTSTR
is just a matter of calling c_str
. It's when you're changing between ANSI and UTF-16 characters that MultiByteToWideChar
(and its inverse WideCharToMultiByte
) comes into the picture.