Convert Lptstr to Char*

Convert lptstr to char*

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)

C++: convert LPTSTR to char array

LPTSTR is a (non-const) TCHAR string. Depends if it is Unicode or not it appears. LPTSTR is char* if not Unicode, or w_char* if so.

If you are using non-Unicode strings LPTSTR is just a char*, otherwise do:

size_t size = wcstombs(NULL, p, 0);
char* CharStr = new char[size + 1];
wcstombs( CharStr, p, size + 1 );

Also, this link can help:

Convert lptstr to char*

C++ LPCTSTR to char*

In MFC the easiest is to convert through CStringA (provided that resulting buffer will be a read-only argument):

LPCTSTR pszA = ...
CStringA sB(pszA);
const char* pszC = sB;
char* pszD = const_cast<char*>(pszC);

Other options are available and were discussed:

  • c++ convert from LPCTSTR to const char *
  • How to convert from LPCTSTR to LPSTR?
  • WideCharToMultiByte, T2A macros etc.

Convert LPTSTR to string or char * to be written to a file

Most solutions presented in the other threads unnecessarily convert to an obsolete encoding instead of an Unicode encoding. Simply use reinterpret_cast<const char*> to write UTF-16 files, or convert to UTF-8 using WideCharToMultiByte.

To depart a bit from the question, using LPTSTR instead of LPWSTR doesn't make much sense nowadays since the old 9x series of Windows is completely obsolete and unsupported. Simply use LPWSTR and the accompanying "wide character" (i.e., UTF-16 code unit) types like WCHAR or wchar_t everywhere.

Here is an example that (I hope) writes UTF-16 or UTF-32 (the latter on Linux/OS X):

#include <fstream>
#include <string>

int main() {
std::ofstream stream("test.txt"); // better use L"test.txt" on Windows if possible
std::wstring string = L"Test\n";
stream.write(reinterpret_cast<const char*>(string.data()), string.size() * sizeof(wchar_t));
}

Convert char[] array to LPTSTR in vc++

You are compiling for Unicode, so LPTSTR expands to wchar_t*. But you have ANSI data, char*. In that case it is simplest to call CreateProcessA and pass the ANSI data.

BOOL retval = CreateProcessA(..., TestExePath, ...));

If you want to avoid using ANSI functions then you can stick to wchar_t arrays.

whar_t exepath[MAX_PATH + 100]; // enough room for cwd and the rest of command line
GetCurrentDirectory(MAX_PATH, exepath);
wcscat(exepath, L"\\pwrtest.exe /sleep /c:1");
BOOL retval = CreateProcess(..., exepath, ...);

Note that I switched from getcwd to GetCurrentDirectory in order to get a wide char version of the working directory.

Note also that your code should check for errors. I neglected to do that here due to laze. But in your real code, you should not be as lazy as I have been.


The fact that you had to cast should have set off warning signals for you. Well, judging from the question, it probably did. When you write:

appPath = (LPTSTR)TestEXEPath;

That simply tells the compiler to treat TestEXEPath as LPTSTR whether or not it really is. And the fact that the program won't compile without the cast tells you that TestEXEPath is not LPTSTR. The cast does not change that reality, it merely shuts the compiler up. Always a bad move.

Only first character is assigned converting LPCTSTR to char*

It is much more useful to just pick a character set (wchar_t, or char), and just stick to it, in your application, since trying to use TCHAR, when trying to support both, may cause you some headaches. To be fair, today, you can just, safely, use wchar_t (or WCHAR, since from the current types you are using, I suspect that you are using Windows headers).

The problem that you have, is because casting a pointer does not have any impact on its contents. And, since, typically wchar_t is 2 bytes in size, while char is 1 byte in size, storing the value, that fits inside a char, in wchar_t, leaves 2nd byte of wchar_t set to \0. And when you try to print null(\0)-terminated string of wchar_ts as a string of chars, the printing function reaches the \0 character after reading the first symbol, and assumes it is the end of the string. \0 character in wchar_t is 2 bytes long.

For example, the string

LPCWSTR test = L"Hi!";

is stored in memory as:

48 00 69 00 21 00 00 00

If you want to convert between the wchar_t version of the string to char version, or vice-versa, there exist some functions, that can do the conversion, and since I noticed that you probably are using Windows headers (from LPCTSTR define), those functions are WideCharToMultiByte/ MultiByteToWideChar.

You may now start to think: I am not using wchar_t! I am using TCHAR!

Typically TCHAR is defined in the following way:

#ifdef UNICODE
typedef WCHAR TCHAR;
#else
typedef char TCHAR;
#endif

So you could do similar handling in your conversion code:

template<int N>
bool GetChar(LPCTSTR var, char (&out)[N])){
#ifdef UNICODE
return WideCharToMultiByte (CP_ACP, 0, var, -1, out, N, NULL, NULL) != 0;
#else
return strcpy_s (out, var) == 0;
#endif
}

Note, the return value of GetChar function is true if the function Succeeds; false - otherwise.

Concatenating LPTSTR with const char* (Win32 C++)

Adding two character pointers does not concatenate the strings, it just adds the two pointer values (as "numbers"). So you end up with an invalid pointer.

Also, typecasting from LPTSTR to char* is not a good idea, as TCHAR can be wide character as well, depending on the current build settings.
(in the fact, you are casting a LPTSTR to char, not to pointer, which is even more wrong)

I think the easiest would be to convert both strings to std::string (or wstring), there you can use the '+' operator to do the concatenation.

One possibility to do that:

const std::wstring strPathToFile = cvt2wstring(strPathToSource) + cvt2wstring(PATH_TO_FILE);

cvt2wstring defined as:

#include <codecvt>
#include <string>

std::wstring cvt2wstring(const char * str)
{
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t> > converter;
return converter.from_bytes(str);
}

std::wstring cvt2wstring(const wchar_t * str)
{
return str;
}

Depending on the actual type, it should choose the appropriate overload.

For the opposite conversion to std::string (so that you can use the regular std::ifstream) you can switch the direction:

std::string cvt2string(const char * str)
{
return str;
}

std::string cvt2string(const wchar_t * str)
{
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t> > converter;
return converter.to_bytes(str);
}

For me, the ifstream::open() seems to work with wstring (but it might be MSVC extension as the C++ standard does not provide that - anyway if you use TCHAR & comp. you probably target Windows and MSVC).



Related Topics



Leave a reply



Submit