C++ Convert from Lpctstr to Const 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.

Converting 'const char*' to 'LPCTSTR' for CreateDirectory

std::string is a class that holds char-based data. To pass a std::string data to API functions, you have to use its c_str() method to get a char* pointer to the string's actual data.

CreateDirectory() takes a TCHAR* as input. If UNICODE is defined, TCHAR maps to wchar_t, otherwise it maps to char instead. If you need to stick with std::string but do not want to make your code UNICODE-aware, then use CreateDirectoryA() instead, eg:

#include "stdafx.h"
#include <string>
#include <windows.h>

int main()
{
std::string FilePath = "C:\\Documents and Settings\\whatever";
CreateDirectoryA(FilePath.c_str(), NULL);
return 0;
}

To make this code TCHAR-aware, you can do this instead:

#include "stdafx.h"
#include <string>
#include <windows.h>

int main()
{
std::basic_string<TCHAR> FilePath = TEXT("C:\\Documents and Settings\\whatever");
CreateDirectory(FilePath.c_str(), NULL);
return 0;
}

However, Ansi-based OS versions are long dead, everything is Unicode nowadays. TCHAR should not be used in new code anymore:

#include "stdafx.h"
#include <string>
#include <windows.h>

int main()
{
std::wstring FilePath = L"C:\\Documents and Settings\\whatever";
CreateDirectoryW(FilePath.c_str(), NULL);
return 0;
}

Cannot convert argument 1 from 'const char [5]' to 'LPCTSTR'

SetWindowTextW() takes a character pointer to the string's data where your string data consists of regular chars, but your function most likely expects a unicode string, so you cannot input string types directly. You need to use L"thisismystring"

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.

cannot convert 'const char*' to 'LPCWSTR {aka const wchar_t*}'

The Windows CreateFile function is actually a macro that expands to one of:

  • CreateFileA, which takes a file path of type const char*
  • CreateFileW, which takes a file path of type const wchar_t*.

(The same is true for most of the functions in the Windows API that take a string.)

You're declaring the parameter const char* ComName, but apparently compiling with UNICODE defined, so it's calling the W version of the function. There's no automatic conversion from const wchar_t* to const char*, hence the error.

Your options are to:

  1. Change the function parameter to a UTF-16 (const wchar_t*) string.
  2. Keep the char* parameter, but have your function explicitly convert it to a UTF-16 string with a function like MultiByteToWideChar.
  3. Explicitly call CreateFileA instead of CreateFile.
  4. Compile your program without UNICODE, so that the macros expand to the A versions by default.
  5. Kidnap a prominent Microsoft developer and force him to read UTF-8 Everywhere until he agrees to have Windows fully support UTF-8 as an “ANSI” code page, thus freeing Windows developers everywhere from this wide-character stuff.

Edit: I don't know if a kidnapping was involved, but Windows 10 1903 finally added support for UTF-8 as an ANSI code page.

Value of type const char * cannot be assigned to an entity of type LPSTR

A string literal is of type const char[N], its contents must not be modified. The ability to implicitly convert string literals to char* was only ever there in C++ for backwards compatibility with C. It's a very dangerous thing, has been deprecated basically forever, and was finally removed in C++11. Visual Studio 2017 switched the default language standard to C++14, which is most likely the reason why your code stopped working there. If you absolutely, positively, definitely know for sure that the string pointed to won't be modified, then you can use a const_cast

MENUITEMINFO mii = { 0 };

mii.cbSize = sizeof(MENUITEMINFO);
mii.fMask = MIIM_TYPE;
mii.fType = MFT_STRING;
mii.dwTypeData = const_cast<char*>("item 1");

Ideally, you would just use const char*, but interop with some old C APIs, unfortunately, sometimes requires the use of const_cast. Before you do this sort of thing, always check the API documentation to make sure that there is no way the API will attempt to modify the contents of the string.

In the case of your MENUITEMINFO here, the reason why the dwTypeData is a char* rather than a const char* is most likely that the struct is intended to be used with both GetMenuItemInfo and SetMenuItemInfo where the former expects a pointer to a buffer in which it will write a string while the latter expects a pointer to a buffer from which it will read a string…

error C2440: '=': cannot convert from 'const char *' to 'LPCWSTR'

What you need to know about the windows API is that it comes in 2 flavors ,namely UNICODE flavor and non-UNICODE flavor.

When you include windows.h

the flavor selected depends on whether UNICODE is defined.

Many if not most WINAPI structures and function are just macros that basically just add either a W or an A to the macro-name to get the real name of the thing you want.

The UNICODE flavor requires character types of wchar_t and non-UNICODE takes char types (or pointers to them).

So you either must use the non-macro names for structs and/or functions or adjust your usage of types to the required macro-definition (in your case use std::wstring in stead of std::string).



Related Topics



Leave a reply



Submit