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_t
s as a string of char
s, 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
How to Select a Random Element in Std::Set
Passing Variable Number of Arguments with Different Type - C++
How to Check If Window Is "Always on Top"
Why Do Objects Returned from Bind Ignore Extra Arguments
C++ Concept That Requires a Member Function with an Outputiterator as Parameter
C++ Visual Studio "Non-Standard Syntax; Use '&' to Create a Pointer to Member"
How Does C++ Preprocessors Work
How to Typedef a Function Pointer with the C++11 Using Syntax
How to Update Gcc in Mingw on Windows
Order of Calling Base Class Constructor from Derived Class Initialization List
What Does "Void *(*)(Void *)" Mean in C++
Cmake Cannot Determine Linker Language for Target
Is There an Intra-Process Local Pipe in Qt
Using Boost::Iostreams::Mapped_File_Source with Std::Multimap
Problems with Move Constructor and Move Overloaded Assignment Operator