How to convert std::wstring to a const TCHAR*? - c++

I have the following wstring:
std::wstring testVal("Test");
Which I need to place inside this value:
static const TCHAR* s_test_val;
So far I have tried:
static const TCHAR* s_test_val = (const wchar_t*) testVal.c_str();
static const TCHAR* s_test_val = (wchar_t*) testVal.c_str();
static const TCHAR* s_test_val = (TCHAR*) testVal.c_str();
static const TCHAR* s_test_val = (TCHAR*) testVal;
But without success; s_test_val keeps appearing as an empty string.

static const TCHAR* s_test_val = testVal.c_str();
This one is correct on the condition that UNICODE is defined in which case TCHAR will be an alias of wchar_t.
If UNICODE isn't defined, then you would need to perform some conversion, but it might not be worth the effort to support non-unicode builds. Your attempt that uses a cast would silently do the wrong thing in that case while this one safely produces an error.
In case you don't care about non-unicode support (and I cannot think of a reason why anyone would), then I recommend minimising the use of TCHAR entirely.

Don't use TCHAR unless Windows 9x support is essential. Additionally, your static pointer pointing to an automatic variable is very suspicious. You either want:
static wchar_t constexpr const* s_test_val = L"Test";
or
std::wstring testVal = L"Test";
wchar_t const* s_test_val = testVal.c_str();
or
std::wstring testVal = L"Test";
auto const s_test_val = testVal.c_str();

Related

How to convert char* to TCHAR in Unreal Engine 4?

For example,
const char* bytes = "somemultibytecharacter一些宽字符";
size_t n = strlen(bytes);
How to convert bytes to FString or TCHAR* in Unreal Engine C++ code?
I know I can convert with std::mbstowcs or MultiByteToWideChar, but I'm trying to find a UE4 alternative.
Just use FString(int32 InCount, const CharType* InSrc).
Usage:
const char* bytes = "somemultibytecharacter一些宽字符";
size_t n = strlen(bytes);
const FString& Str = FString(n, bytes);
const TCHAR* Text = *Str;
Note, in my copy of Unreal Engine 4, TCHAR is wchar_t:
typedef wchar_t WIDECHAR;
typedef WIDECHAR TCHAR

Safer string copy function in VC++ but how to handle TCHAR*?

I was fixing all C4996 warnings which is MS's proposal.
replaced sprintf with sprint_s
replaced _tcscpy with _tcscpy_s
It works without changing parameter with TCHAR[]
TCHAR* test; // a string argument from CLR project
TCHAR target[100];
_tcscpy(target, test);
_tcscpy_s(target, test); // both works fine.
but what about TCHAR*?
I don't know how big the buffer size will be with TCHAR*
TCHAR* test; // a string argument from CLR project
TCHAR* target;
_tcscpy_s(target, ???, test);
Here are what I have looked into:
using strcpy_s for TCHAR pointer (Microsoft Specific)
Microsoft _s functions, are they part of the C++ standard now?
But there is no solution.
I wrote an answer to myself with advice from #dxiv.
TCHAR* to TCHAR*
TCHAR* src= new TCHAR[??]; // check whether it is initialized.
TCHAR* dest= new TCHAR[??];
const int BUFFER= _tsclen(src) + 1;
_tcscpy_s(dest, BUFFER, src);
TCHAR[] to TCHAR*
TCHAR src[??] = _T("something...");
TCHAR* dest= new TCHAR[??];
const int BUFFER= _countof(src);
_tcscpy_s(dest, BUFFER, src);
TCHAR[] to TCHAR[]
TCHAR src[??] = _T("something...");
TCHAR dest[??] = _T("");
_tcscpy_s(dest, src);

cannot convert from 'const char *' to 'LPCTSTR'

I'm trying to convert string to 'LPCTSTR', but, i got following error.
Error :
cannot convert from 'const char *' to 'LPCTSTR'
code:
std::string str = "helloworld";
LPCTSTR lp = str.c_str();
Also, tried :
LPCTSTR lp = (LPCTSTR)str.c_str();
But, print garbage value.
LPCTSTR means (long pointer to constant TCHAR string).
A TCHAR can either be wchar_t or char based on what your project settings are.
If, in your project settings, in the "General" tab, your character set is "Use Multi-byte character set" then TCHAR is an alias for char. However, if it's set to "Use Unicode character set" then TCHAR is an alias for wchar_t instead.
You must be using the Unicode character set, so:
LPCTSTR lp = str.c_str();
Is in reality:
// c_str() returns const char*
const wchar_t* lp = str.c_str();
This is why you're getting the error:
cannot convert from 'const char *' to 'LPCTSTR'
Your line:
LPCTSTR lp = (LPCTSTR)str.c_str();
Is in reality:
const wchar_t* lp = (const wchar_t*) std.c_str();
In a std::string, the chars are single bytes, having a wchar_t* point to them will expect that each character is 2+ bytes instead. That's why you're getting nonsense values.
The best thing to do would be as Hans Passant suggested - not to use typedefs based on TCHAR. In your case, do this instead:
std::string str = "helloworld";
const char* lp = str.c_str(); // or
LPCSTR lp = str.c_str();
If you want to use wide chars, which Windows calls Unicode, then you can do this:
std::wstring wstr = L"helloword";
const wchar_t* lp = wstr.c_str() // or
LPCWSTR lp = wstr.c_str();

How to concatenate char* and LPWSTR string?

I want to use MoveFile function, this function use two LPWSTR arguments, but I have one char* and LWSTR, how to concatenate them?
//move file
LPWSTR latestFile = L"test.SPL";
char* spoolFolder = "C:\\Windows\\System32\\spool\PRINTERS\\";
LPWSTR fileToMove = spoolFolder + latestFile;
BOOL moved = MoveFile(latestFile, L"C:\\UnprocessedFiles\\" + latestFile);
Just for clarification, LPWSTR is a typedef for wchar_t*. You can use wcscat_s to conctenate strings of this form. Your one char* string should just be changed to be of the same type, since you have it there as a simple literal (just prefix the literal with L and change the declared type). Since you tagged this as C++, however, you can do all of this more simply by using the std::wstring class.
std::wstring latestFile = wstring("test.SPL");
std::wstring spoolFolder = wstring("C:\\Windows\\System32\\spool\PRINTERS\\");
std::wstring fileToMove = spoolFolder + latestFile;
BOOL moved = MoveFile(latestFile.c_str(), fileToMove.c_str());
In deed, LPWSTR is just a typdef for w_char*. so if you consult MSDN you will see that:
typded wchar_t* LPWSTR;
here the w_char* means that your string will be encoded as UNICODE not ANSI scheme. So under windows a UNICODE string will be an UTF16 one ( 2 bytes for each char).
std::wstring is also a typedef for std::basic_string<wchar_t,char_traits<>> so by declaring your inputs as wstring and calling wasting.c_str() this will do the stuff.

How do I convert a int to LPCTSTR? Win32

I would like to display an int value in a win32 MessageBox. I have read some different methods to perform this cast. Can someone provide me with a good implementation.
New to Win32 programming so go easy :)
update
So this is what i have so far. It works.. but the text looks like Chinese or some other double byte characters. I am not groking the Unicode vs. not Unicode types. Can someone help me understand where I am going wrong?
int volumeLevel = 6;
std::stringstream os;
os<<volumeLevel;
std::string intString = os.str();
MessageBox(plugin.hwndParent,(LPCTSTR)intString.c_str(), L"", MB_OK);
Converting for MFC like belov :
int number = 1;
CString t;
t.Format(_T("%d"), number);
AfxMessageBox(t);
I used and it worked for me.
LPCTSTR is defined like this:
#ifdef UNICODE
typedef const wchar_t* LPCTSTR;
#else
typedef const char* LPCTSTR;
#endif
std::string::c_str() returns a const char* only. You can't convert a const char* directly to const wchar_t*. Normally the compiler will complain about it, but with the LPCTSTR cast you end up forcing the compiler to shut up about it. So of course it doesn't work as you expect at runtime. To build on what you have in your question, what you probably want is something like this:
// See Felix Dombek's comment under OP's question.
#ifdef UNICODE
typedef std::wostringstream tstringstream;
#else
typedef std::ostringstream tstringstream;
#endif
int volumeLevel = 6;
tstringstream stros;
stros << volumeLevel;
::MessageBox(plugin.hwndParent, stros.str().c_str(), L"", MB_OK);
nA few ways:
int value = 42;
TCHAR buf[32];
_itot(value, buf, 10);
another more friendly way for your case:
int value = 42;
const size_t buflen = 100;
TCHAR buf[buflen];
_sntprintf(buf, buflen - 1, _T("the value is %d"), value);
int OurVariable;
LPCWSTR result=(to_string(OurVariable).c_str());
or
LPCWSTR result=LPCSTR(to_string(OurVariable).c_str());
or
LPCSTR result=(to_string(OurVariable).c_str());
it
really works
Use _T() decorator for Unicode-aware code:
int number = 1;
CString t;
t.Format(_T("%d"), number);
AfxMessageBox(t);
ref: https://social.msdn.microsoft.com/Forums/vstudio/en-US/f202b3df-5849-4d59-b0d9-a4fa69046223/how-to-convert-int-to-lpctstr?forum=vclanguage