Would anyone happen to know how to convert type LPTSTR
to char *
in C++?
8 Answers
Depends if it is Unicode or not it appears. LPTSTR is char* if not Unicode, or w_char* if so.
Discussed better here (accepted answer worth reading)

- 14,891
- 10
- 61
- 93
Here are a lot of ways to do this. MFC or ATL's CString, ATL macros, or Win32 API.
LPTSTR szString = _T("Testing");
char* pBuffer;
You can use ATL macros to convert:
USES_CONVERSION;
pBuffer = T2A(szString);
CString:
CStringA cstrText(szString);
or the Win32 API WideCharToMultiByte
if UNICODE
is defined.

- 333,147
- 50
- 533
- 760

- 431
- 2
- 3
-
1The aforementioned use of ATL conversion macros is obsolete (probably that use was valid for VC6 and ATL3, but since VC7 things changed). `T2A` macro with `USES_CONVERSION` is deprecate. It's better to use ATL7+ [conversion helpers](http://msdn.microsoft.com/en-us/library/87zae4a3(v=vs.80).aspx) like `CT2A` (without `USES_CONVERSION`): `CT2A ansiBuffer(szString);` – May 21 '12 at 17:28
-
CT2A doesn't work for Chinese. I recommend wcstombs. But you need to warp it in _UNICODE and non_UNICODE edition. – Zhang Jan 18 '19 at 00:54
If your compiler Character Setting is set to Unicode Character Set, then LPTSTR will be interpreted as wchar_t*. In that case Unicode to Multibyte character conversion is required.
(In Visual Studio, setting is located at Project Properties\Configuration Properties\General\Character Set)
The sample code below should give an idea:
#include <windows.h>
/* string consisting of several Asian characters */
LPTSTR wcsString = L"\u9580\u961c\u9640\u963f\u963b\u9644";
//LPTSTR wcsString = L"OnlyAsciiCharacters";
char* encode(const wchar_t* wstr, unsigned int codePage)
{
int sizeNeeded = WideCharToMultiByte(codePage, 0, wstr, -1, NULL, 0, NULL, NULL);
char* encodedStr = new char[sizeNeeded];
WideCharToMultiByte(codePage, 0, wstr, -1, encodedStr, sizeNeeded, NULL, NULL);
return encodedStr;
}
wchar_t* decode(const char* encodedStr, unsigned int codePage)
{
int sizeNeeded = MultiByteToWideChar(codePage, 0, encodedStr, -1, NULL, 0);
wchar_t* decodedStr = new wchar_t[sizeNeeded ];
MultiByteToWideChar(codePage, 0, encodedStr, -1, decodedStr, sizeNeeded );
return decodedStr;
}
int main(int argc, char* argv[])
{
char* str = encode(wcsString, CP_UTF8); //UTF-8 encoding
wchar_t* wstr = decode(str, CP_UTF8);
//If the wcsString is UTF-8 encodable, then this comparison will result to true.
//(As i remember some of the Chinese dialects cannot be UTF-8 encoded
bool ok = memcmp(wstr, wcsString, sizeof(wchar_t) * wcslen(wcsString)) == 0;
delete str;
delete wstr;
str = encode(wcsString, 20127); //US-ASCII (7-bit) encoding
wstr = decode(str, 20127);
//If there were non-ascii characters existing on wcsString,
//we cannot return back, since some of the data is lost
ok = memcmp(wstr, wcsString, sizeof(wchar_t) * wcslen(wcsString)) == 0;
delete str;
delete wstr;
}
On the other hand, if your compiler Character Setting is set to Multibyte, then LPTSTR will be interpreted as char*.
In that case:
LPTSTR x = "test";
char* y;
y = x;
Also see:
Another discussion about wchar_t conversion: How do you properly use WideCharToMultiByte
MSDN Article: http://msdn.microsoft.com/en-us/library/dd374130(v=vs.85).aspx
Valid Code Page Identifiers: http://msdn.microsoft.com/en-us/library/dd317756(v=vs.85).aspx
char * pCopy = NULL;
if (sizeof(TCHAR) == sizeof(char))
{
size_t size = strlen(pOriginal);
pCopy = new char[size + 1];
strcpy(pCopy, pOriginal);
}
else
{
size_t size = wcstombs(NULL, pOriginal, 0);
pCopy = new char[size + 1];
wcstombs(pCopy, pOriginal, size + 1);
}

- 299,747
- 42
- 398
- 622
-
If i use this way i get this error C2664: 'strlen' : cannot convert parameter 1 from 'LPTSTR' to 'const char *' – Oleksandr Fentsyk May 21 '12 at 09:59
OK, so lets say that you HAVE to use Unicode. And you use some functions like LookupAccountSid, that are required for your program to function - but they return LPTSTR for important information you NEED to process as a string (for whatever reason - it's programming, stuff like this happens)
Now, if you were using multibyte - this wouldn't be an issue. But there is a way to solve it. This is my method and is admittedly sloppy. But nonetheless you should be able to see how it works.
const std::wstring &wstring = AcctName; // AcctName being my LPTSTR string
int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstring[0], (int)wstring.size(), NULL, 0, NULL, NULL);
std::string strTo(size_needed, 0);
WideCharToMultiByte(CP_UTF8, 0, & wstring[0], (int)wstring[0], &strTo[0], size_needed, NULL, NULL);
char* charUserName = new char[strTo.size() + 1];
// Set charUserName via copying
std::copy(strTo.begin(), strTo.end(), charUserName);
charUserName[strTo.size()] = '\0';
SetUPI(charUserName); // charUserName being my converted char * -
// You don't need this last part - but this is an example of passing to method
// that takes a string
Any questions just ask. I realise this is an old post - but I like to post for people in the furture that come looking. (people like me)

- 1,945
- 1
- 10
- 7
I hope this helps someone, because it took me a while to figure out how to do it.
First of all, LPTSTR
is of pointer type and it is basically equivalent to TCHAR*
(assuming that <tchar.h>
is included).
Note that the size of TCHAR
varies based of the character encoding type. i.e. if unicode is defined, TCHAR
is equal to wchar_t
, otherwise it is char
.
Naturally, if you convert a wide character to a normal char
, you can only keep the LSB and may lose some data. This was somehow irritating for me. so I wrote the following code. Its main advantage is doing the conversion without losing any data.
By the way, if you are okay with data loss, then wcstombs
does the job.
#include <cstring>
#include <algorithm>
#include <tchar.h>
void lptstr2str(LPTSTR tch, char* &pch) // or (TCHAR* tch, char* &pch)
{
#ifndef UNICODE
std::memcpy(pch, tch, strlen(tch) + 1);
#else
size_t n =
sizeof(TCHAR) / sizeof(char)* wcsnlen(tch, std::string::npos);
pch = new char[n + 1];
std::memcpy(pch, tch, n + 1);
int len = n - std::count(pch, pch + n, NULL);
std::remove(pch, pch + n, NULL);
pch[len] = NULL;
#endif
}

- 1,840
- 26
- 41
I was missing some simple example so here it is:
(for me char* is identical to char[])
LPCTSTR myLPCTSTR = getLPCTSTR();
TCHAR myT[500];
wcscpy(myT,myLPCTSTR);
char myC[500];
sprintf(myC, "%S", myT);

- 1,173
- 18
- 24
no doubt many (eg, us unix folk) will recoil in horror at the mad-hatter Microserf doublespeak - "if your compiler is in Unicode mode, use LPWSTR or stick a "T_" in front of it, but only if it's a static string, which is the same as an "L", or use T2A() if using ATL, but that's now outdated, or use VARIANT but not if linking with COM/OLE"...).
The "if (sizeof(TCHAR) == sizeof(char))" listed on this page is a logical attempt at a nice solution, but it won't compile - either the if-true won't compile or if-false wont' compile, depending on your compiler flags (Aaargh!). For a write-and-forget portable solution you'll need to resort to the [too-generic named] UNICODE macro. I offer this adaptation of the previous code:
string mfc_to_zstring (CString &sref)
{
char nojoy[65536];
char *ptr, *psin = NULL;
string sot;
LPCTSTR p = sref;
#if UNICODE
if (sizeof(TCHAR) != sizeof(char))
{
size_t n = wcstombs(NULL, p, 0);
if (n > 65530)
{
psin = new char[n + 1];
wcstombs(psin, p, n + 1);
ptr = psin;
}
else
{
wcstombs(nojoy, p, n + 1);
ptr = nojoy;
}
sot = ptr;
if (psin != NULL)
delete psin;
}
else
{ std::cerr << "Aaargh! Microsoft horror.\n"; exit(1); }
#else
if (sizeof(TCHAR) == sizeof(char))
{
const char *ptr = p;
sot = ptr;
}
else
{ std::cerr << "Aaargh! You should never see this line\n"; exit(1); }
#endif
return sot;
}

- 9
- 3