Convert std::string to LPCWSTR (best way in c++)
Hi!
How can I convert an std::string to a LPCWSTR? What is the best way to do it in C++?
Thanks.
"Ciao guagliò!"
Respuestas
FabioDeSantis wrote: How can I convert an std::string to a LPCWSTR? What is the best way to do it in C++?
Instead of using a std::string, use a std::wstring (also called a std::basic_string<wchar_t>).
I get the feeling you want to pass a std::string type to a Win32 API. Those APIs don't take LPCWSTRs (or even LPCSTRs), they take a LPCTSTR (long pointer to a tchar-string). In this case, your question should have been: "How do I convert a std::string to a LPCTSTR?"
Instead of using a std::string use a std::basic_string<TCHAR>.
Todas las respuestas
FabioDeSantis wrote: How can I convert an std::string to a LPCWSTR? What is the best way to do it in C++?
Instead of using a std::string, use a std::wstring (also called a std::basic_string<wchar_t>).
I get the feeling you want to pass a std::string type to a Win32 API. Those APIs don't take LPCWSTRs (or even LPCSTRs), they take a LPCTSTR (long pointer to a tchar-string). In this case, your question should have been: "How do I convert a std::string to a LPCTSTR?"
Instead of using a std::string use a std::basic_string<TCHAR>.
std::wstring s2ws(const std::string& s)
{
int len;
int slength = (int)s.length() + 1;
len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
wchar_t* buf = new wchar_t[len];
MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
std::wstring r(buf);
delete[] buf;
return r;
}std::string s;
#ifdef UNICODE
std::wstring stemp = s2ws(s); // Temporary buffer is required
LPCWSTR result = stemp.c_str();
#else
LPCWSTR result = s.c_str();
#endif- Propuesto como respuestaBRIGHTEST STAR miércoles, 09 de septiembre de 2009 10:39
Perfect! Thank you so much!
"Ciao guagliò!"
Although you can use this function to convert a ANSI string to wide characters (or if you're comfortable with C++ iostreams:
std::wstring ts2ws(const std::basic_string<TCHAR> &s)
{
/* exception safe */
std::basic_ostringstream<TCHAR> buf;
buf << s;
return buf.str();}
), (or if you have the CRT wcstombs), (or if you're using the secure CRT wcstombs_s), (or if you're using ATL A2W), (or if you're using MFC CString), (or if you're using .NET PtrToStringChars), (or whatever the libraries your API provides), etc etc.
IMO, you shouldn't need to make use of these conversions at all.
Why?
Ideally, your strings should all be of one datatype (either all char, or all wchar_t, or all TCHAR). This promotes consistency (a vital facet of reusable architectures). Use of these conversion macros are an indication of a flaw in your design. In the best case scenario, character conversion functions represent performance bottlenecks. In the worst case scenario, they are the source of security bugs.
If you need to make use of a library that uses one of the other character datatypes, then either rewrite all your code to be the same as that datatype (eg. instead of using string, use wstring, or a "tstring"), or rewrite that library to fit with your datatype (replace char with wchar_t / TCHAR).
If this means you have to rewrite your entire program from scratch, then rewrite your program from scratch (if you leave it till later, it will just get harder to port). If you don't perform the upgrade, you will leave your app slower and less secure than it can be.
One of my pet peeves occurs when I need to make use a library that doesn't use wchar_t / TCHARs. I have to waste the rest of the day / week rewriting that library to use the wide character functions. Then I end up ditching that library, when I find out out that ignorance of unicode is the least of the problems plaguing the library.
I recommend make new software, using std:wstring only, because all new Microsoft systems are UNICODE internally and there is only a small count of working Windows9x systems.
Using of TCHAR is a poor design in Windows, unfortunately, because we should create two different exe files for unicode and ansi environment.
Using of a std::wstring is simple. There is a fastest way to convert to it from Windows API functions or use it for Windows API calling.
For compatible conversions use this code:
std::string ws2s(const std::wstring& s)
{
int len;
int slength = (int)s.length() + 1;
len = WideCharToMultiByte(CP_ACP, 0, s.c_str(), slength, 0, 0, 0, 0);
char* buf = new char[len];
WideCharToMultiByte(CP_ACP, 0, s.c_str(), slength, buf, len, 0, 0);
std::string r(buf);
delete[] buf;
return r;
}This function and s2ws() are checked for bugs. Only one problem may be available, if you will use these functions in expressions with c_str(). You should create a local variable in some cases, because C++ may call a string destructor and destroy string object before API calling, so this API function may get a pointer to a destructed memory.
Andrew Revvo wrote: I recommend make new software, using std:wstring only, because all new Microsoft systems are UNICODE internally The Windows API is TCHAR, and regardless of whether it uses unicode or ansi internally, the API is the only thing you access. Therefore, if you use the Windows API, you need to access it with TCHAR.
Andrew Revvo wrote: and there is only a small count of working Windows9x systems. For the remaining Windows9x systems, you always have the Microsoft Layer for Unicode, which allows your unicode app to run on these systems.
Andrew Revvo wrote: Using of TCHAR is a poor design in Windows, unfortunately, because we should create two different exe files for unicode and ansi environment. Although TCHAR's primary use is cited for developing an ansi and unicode EXE, its use extends to more than just that. You can use it to create libraries that work with both unicode and ansi projects with minimal pain. Whereas with ANSI apps, you have to rewrite the entire project to convert it to unicode, with TCHAR apps, you just need to define UNICODE.
Having said that, DLLs should be developed Petzold-Windows style (ie. have both a W entry point and A entry point).
std::string ws2s(const std::wstring& s)
{
int slength = (int)s.length() + 1;
int len = WideCharToMultiByte(CP_ACP, 0, s.c_str(), slength, 0, 0, 0, 0);
char* buf = new char[len];
WideCharToMultiByte(CP_ACP, 0, s.c_str(), slength, buf, len, 0, 0);
std::string r(buf); // If this throws an exception, you'll leak memory. It will be slightly easier to use a std::vector instead, which does self checking.
delete[] buf;
return r;
}
Very helpful. In case this is any use, here's an example I developed (with help!) for a sort of reverse operation:
#define
BUFSIZE MAX_PATHTCHAR Buffer[BUFSIZE];
DWORD dwRet;
dwRet = GetCurrentDirectory(BUFSIZE, Buffer);
std:
tring strcurpath;#ifdef
UNICODEsize_t i;
char *pMBBuffer = (char *)malloc( BUFSIZE );wcstombs_s(&i, pMBBuffer, (size_t)BUFSIZE, Buffer, (size_t)BUFSIZE );
strcurpath = pMBBuffer;
#else
strcurpath = Buffer;
#endif
- at the end of the day std:
tring will do the job, you can use UTF-8 encoding if you are in need of 3rd part language support. This simplifies things to a degree, to bad the standards group was unwilling to deal with the fact that not everyone speaks C++ fluently.
- Perhaps a more simple way :
std::wstring s2ws (const std::string& s)
{
std::wstring ws;
ws.assign (s.begin (), s.end ());
return ws;
}
... and so
std::string ws2s (const std::wstring& ws)
{
std::wstring s;
s.assign (ws.begin (), ws.end ());
return s;
}
- It is simple but it is wrong. You cannot ignore character encoding, you must use MultiByteToWideChar().
Hans Passant. - MultiByteToWideChar
Char * to Wide char ptr
that is
Char * wchar_t *
Code:
int len = lenOfchPtr+1;
wchar_t *wText = new wchar_t[len];
memset(wText,0,len);
MultiByteToWideChar( CP_ACP, NULL,chPtr, -1, wText,len );
Anadi Kumar, Indo-Nepal Border Jogbani, Araria BIhar, PIN-854328 - I suggest using TCHAR instead of wchar_t. It will be either char or wchar depending on UNICODE define.
please pay attention to \0 in string::format!!!
array<TCHAR>^ str = String::Format("<YOUR STRING HERE>\0", i)->ToCharArray();
TCHAR *tr = new TCHAR[str->Length];
for(int n = 0; n < str->Length; tr[n] = str[n], n++);
handle = CreateFile(tr, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
delete[] tr;
Beef

