How to convert CString to const char*? - mfc

i want to convert CString to const char*, i used that const char* cstr = (LPCTSTR)CString; but it doesn't compile,so how to do that, or how to convert CString to double, i used this method _tstof but it returns 0 when i passed a CString to it, so i want to convert CString to const char* inorder to pass the converted value to the method atof(), here's an example:
int nTokenPos=0;
CString leftDigit,rightDigit;
double firstNum,secondNum;
if(dialog->myValue.Find('X')!=-1){
CString resToken = dialog->myValue.Tokenize(_T("X"), nTokenPos);
leftDigit=resToken;
OutputDebugString(leftDigit);
while(!resToken.IsEmpty())
{
resToken = dialog->myValue.Tokenize(_T("X"), nTokenPos);
rightDigit=resToken;
rightDigit+="\n";
//OutputDebugString(rightDigit);
}
firstNum= _tstof(leftDigit);
secondNum=_tstof(rightDigit);
OutputDebugString(leftDigit);
OutputDebugString(rightDigit);
TRACE( "First_Number %d\n",firstNum); --->OutPuts ZERO
TRACE( "\nSecond_Number %d\n",secondNum); --->OutPuts ZERO
//MathFuncs::MyMathFuncs::Multiply(firstNum,secondNum);
TRACE( "The result %d\n",MathFuncs::MyMathFuncs::Multiply(firstNum,secondNum));

This line
const char* cstr = (LPCTSTR)CString;
doesn't compile because I guess you are building an UNICODE build of your project and therefore _T expands to a 2-byte character (a wide character).
To make this conversion working you could use the ATL macros. Like:
USES_CONVERSION;
const char* cstr = T2A((LPCTSTR)CString);
However, this is not really related to your initial problem as you are using anyways _tstof() which handles the _T issues for you.
[Edited]:
The mistake is somewhere else. The format string of the TRACE is not using the wright placeholder for a float/double. Instead of %d use %f:
CString leftDigit = _T("12.5");
double firstNum = _tstof(leftDigit);
TRACE(_T("%f\n"), firstNum);
I tried this and got 12.50000000 printed in the Output pane of VS.

I am not sure if you are using UNICODE or not. You should use generic text mapping.
Anyway:
CString csTest(_T("Test"));
const TCHAR* cstr = (LPTSTR)(LPCTSTR)csTest;

CString s( _T( "ala bala portocala" ) );
CStringA s2( s );
const char* c = s2;

Related

Can "const char[18]* be changed to an entity of type LPCWSTR(C++)? [duplicate]

After getting a struct from C# to C++ using C++/CLI:
public value struct SampleObject
{
LPWSTR a;
};
I want to print its instance:
printf(sampleObject->a);
but I got this error:
Error 1 error C2664: 'printf' : cannot convert parameter 1 from
'LPWSTR' to 'const char *'
How can I convert from LPWSTR to char*?
Thanks in advance.
Use the wcstombs() function, which is located in <stdlib.h>. Here's how to use it:
LPWSTR wideStr = L"Some message";
char buffer[500];
// First arg is the pointer to destination char, second arg is
// the pointer to source wchar_t, last arg is the size of char buffer
wcstombs(buffer, wideStr, 500);
printf("%s", buffer);
Hope this helped someone! This function saved me from a lot of frustration.
Just use printf("%ls", sampleObject->a). The use of l in %ls means that you can pass a wchar_t[] such as L"Wide String".
(No, I don't know why the L and w prefixes are mixed all the time)
int length = WideCharToMultiByte(cp, 0, sampleObject->a, -1, 0, 0, NULL, NULL);
char* output = new char[length];
WideCharToMultiByte(cp, 0, sampleObject->a, -1, output , length, NULL, NULL);
printf(output);
delete[] output;
use WideCharToMultiByte() method to convert multi-byte character.
Here is example of converting from LPWSTR to char*
or wide character to character.
/*LPWSTR to char* example.c */
#include <stdio.h>
#include <windows.h>
void LPWSTR_2_CHAR(LPWSTR,LPSTR,size_t);
int main(void)
{
wchar_t w_char_str[] = {L"This is wide character string test!"};
size_t w_len = wcslen(w_char_str);
char char_str[w_len + 1];
memset(char_str,'\0',w_len * sizeof(char));
LPWSTR_2_CHAR(w_char_str,char_str,w_len);
puts(char_str);
return 0;
}
void LPWSTR_2_CHAR(LPWSTR in_char,LPSTR out_char,size_t str_len)
{
WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,in_char,-1,out_char,str_len,NULL,NULL);
}
Here is a Simple Solution. Check wsprintf
LPWSTR wideStr = "some text";
char* resultStr = new char [wcslen(wideStr) + 1];
wsprintfA ( resultStr, "%S", wideStr);
The "%S" will implicitly convert UNICODE to ANSI.
Don't convert.
Use wprintf instead of printf:
wprintf
See the examples which explains how to use it.
Alternatively, you can use std::wcout as:
wchar_t *wstr1= L"string";
LPWSTR wstr2= L"string"; //same as above
std::wcout << wstr1 << L", " << wstr2;
Similarly, use functions which are designed for wide-char, and forget the idea of converting wchar_t to char, as it may loss data.
Have a look at the functions which deal with wide-char here:
Unicode in Visual C++

Converting string to LPCTSTR

I encountered a problem during writting my code. I use a function which take as an argument object which type is LPCSTR. The object declaration looks like shown below:
LPCTSTR lpFileName;
Firstly, I used defined variable, which was futher assign to lpFileName like this:
#define COM_NR L"COM3"
lpFileName = COM_NR
Using this manner, I could easily pass lpFileName argument to the function. Anyway, i had to changed the way of defining my port number. Currently i read text from *.txt file and save it as string variable e.g "COM3" or "COM10". The main problem is to convert string to LPCSTR properly. I found good solution but finally it doesn't seem working properly. My code looks like this:
string temp;
\\code that fill temp\\
wstring ws;
ws.assign(temp.begin(),temp.end());
I thought that conversion went correctly, maybe it did and I don't get it because when i print few things it makes me to wonder why it doesn't work as i want:
cout temp_cstr(): COM3
cout LCOM3: 0x40e586
cout ws.c_str(): 0x8b49b2c
Why LCOM3 and ws.c_str() doesn't contain the same? When i pass lpFileName = ws.c_str() to my function, it works uncorretly. On the other hand, passing lpFileName = L"COM3" gives success.
I code using cpp, and IDE is QtCreator
Eventually, I managed with the pitfall using conversion-function s2ws() and doing few operations. I place my soultion here for people who will have similar troubles with converting string. In my first post i wrote that i needed to convert string to LPCTSTR and finally it turned out that argument in my function is not, LPCTSTR but LPCWSTR that is const wchar_t*.
So, soulution:
string = "COM3";
wstring stemp;
LPCWSTR result_port;
stemp = s2ws(port_nr);
result_port = stemp.c_str(); // now passing result_port to my function i am getting success
declaration of s2ws:
wstring s2ws(const std::string& s)
{
int len;
int slength = (int)s.length() + 1;
len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
wchar_t* buf = new wchar_t[len];
MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
std::wstring r(buf);
delete[] buf;
return r;
}
Try to use wostringstream:
string temp;
\\code that fill temp\\
wostringstream ost;
ost << temp.c_str();
wstring ws = ost.str();
I have struggled with this for quite a while. After quite a bit of digging I found this works the best; you could try this.
std::string t = "xyz";
CA2T wt (t.c_str());

C++ WCHAR manipulations

I'm developing a tiny Win32 app in C++.
I've studied C++ fundamentals long time ago, so now I completely confused because of character strings in C++. There were no WCHAR or TCHAR only char and String.
After a little investigation I've decided not to use TCHAR.
My issue is very simple I think, but I can't find clear guide how to manipulate strings in C++. Affected by PHP coding last few years I've expected something simple with strings manipulations and was wrong!
Simply, all I need is to put new data to a character string.
WCHAR* cs = L"\0";
swprintf( cs, "NEW DATA" );
This was my first attempt. When debugging my app I've investigated that swprintf puts only first 2 chars to my cs var. I've resolved my problem this way:
WCHAR cs[1000];
swprintf( cs, "NEW DATA" );
But generally this trick could fail, because in my case new data is not constant value but another variable, that could potentialy be wider, than 1000 chars long. And my code is looks like this:
WCHAR cs[1000];
WCHAR* nd1;
WCHAR* nd2;
wcscpy(nd1, L"Some value");
wcscpy(nd2, L"Another value"); // Actually these vars stores the path for user selected folder
swprintf( cs, "The paths are %s and %s", nd1, nd2);
In this case there is possibility than nd1 and nd2 total character count could be greater than 1000 chars so critical data will be lost.
The question is how can I copy all data I need to WCHAR string declared this way WCHAR* wchar_var; without losing anything?
P.S. Since I'm Russian the question may be unclear. Let me now about that, and I'll try to explain my issue more clear and complex.
In modern Windows programming, it's OK to just ignore TCHAR and instead use wchar_t (WCHAR) and Unicode UTF-16.
(TCHAR is a model of the past, when you wanted to have a single code base, and produce both ANSI/MBCS and Unicode builds changing some preprocessor switches like _UNICODE and UNICODE.)
In any case, you should use C++ and convenient string classes to simplify your code. You can use ATL::CString (which corresponds to CStringW in Unicode builds, which are the default since VS2005), or STL's std::wstring.
Using CString, you can do:
CString str1 = L"Some value";
CString str2 = L"Another value";
CString cs;
cs.Format(L"The paths are %s and %s", str1.GetString(), str2.GetString());
CString also provides proper overloads of operator+ to concatenate strings (so you don't have to calculate the total length of the resulting string, dynamically allocate a buffer for the destination string or check existing buffer size, call wcscpy, wcscat, don't forget to release the buffer, etc.)
And you can simply pass instances of CString to Win32 APIs expecting const wchar_t* (LPCWSTR/PCWSTR) parameters, since CString offers an implicit conversion operator to const wchar_t*.
When you're using a WCHAR*, you are invoking undefined behavior because you have a pointer but have not made it point to anything valid. You need to find out how long the resulting string will be and dynamically allocate space for the string. For example:
WCHAR* cs;
WCHAR* nd1;
WCHAR* nd2;
nd1 = new WCHAR[lstrlen(L"Some value") + 1]; // +1 for the null terminator
nd2 = new WCHAR[lstrlen(L"Another value") + 1];
cs = new WCHAR[lstrlen(L"The paths are and ") + lstrlen(nd1) + lstrlen(nd2) + 1];
wcscpy(nd1, L"Some value");
wcscpy(nd2, L"Another value"); // Actually these vars stores the path for user selected folder
swprintf( cs, L"The paths are %s and %s", nd1, nd2);
delete[] nd1;
delete[] nd2;
delete[] cs;
But this is very ugly and error-prone. As noted, you should be using std::wstring instead, something like this:
std::wstring cs;
std::wstring nd1;
std::wstring nd2;
nd1 = L"Some value";
nd2 = L"Another value";
cs = std::wstring(L"The paths are ") + nd1 + L" and " + nd2;
Suggest to use ATL CStringW class instead of raw WCHAR, it's much more handy. CString is wrapper for dynamically allocated C-string. It will manage string length & allocated memory buffer appropriately after each operation so you wouldn't care on it.
Typical usage:
#include <atlstr.h>
CStringW s;
s.Format(L"The paths are %s and %s", L"Some value", L"Another value");
const WCHAR* wstr = s.GetString(); // To pass to some API that need WCHAR
or
#include <atlstr.h>
CStringW s(L"The paths are ");
s += L"Some value";
s += L" and ";
s += L"Another value";
const WCHAR* wstr = s.GetString(); // To pass to some API that need WCHAR

CString format with Unicode returns wrong character

I'm trying to format a CString using the following code:
const wchar_t * wch = L"μ";
CString str;
str.Format(_T("%c"), wch[0]);
However, instead of str having the value of "μ" it actually is set to "¼". When I debug it, it recognizes wch as "μ".
Further, if I do:
const wchar_t * wch = L"μ";
CString str;
str.Format(_T("%s"), wch);
it gives str with value "¼". (It doesn't seem to show up but there should be a superscript L after the ¼.)
The compiler is set to use unicode, as else where in the program I am able to call _T() and have it evaluate correctly, just not when formatting a CString.
What am I doing wrong?
*Edit: * Doing more debugging shows that the CString Format method's arglist receives a value of "Ü_"
I believe you need to use a "long" char or string format specifier -- so %lc for the wchar_t and %ls or %S for the string.
Try
setlocale(LC_ALL, "");
before calling Format. (Unless you're doing anything unusual, it's enough to call setlocale once near the beginning of your application.)
I see Miu with %c and with %lc
// a1.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <afx.h>
int _tmain(int argc, _TCHAR* argv[])
{
const wchar_t * wch = L"μ";
CString str;
str.Format(_T("%c"), wch[0]);
MessageBox( GetForegroundWindow(), str.GetBuffer(), L"MyChar", MB_OK + MB_ICONHAND );
str.Format(_T("%s"), wch);
MessageBox( GetForegroundWindow(), str.GetBuffer(), L"MyChar", MB_OK + MB_ICONHAND );
return 0;
}

Convert CString to string (VC6)

I want to convert CString to string. (Yup. I know what am I doing. I know the returned string will be incorrect, if CString value range is outside ANSI, but That's Is OK!)
The following code will work under VC2008.
std::string Utils::CString2String(const CString& cString)
{
// Convert a TCHAR string to a LPCSTR
CT2CA pszConvertedAnsiString (cString);
// construct a std::string using the LPCSTR input
std::string strStd (pszConvertedAnsiString);
return strStd;
}
But VC6 doesn't have CT2CA macro. How I can make the code to work as well in both VC6 and VC2008?
Microsoft says that CT2CA replaces T2CA, so try the latter and see if that works.
Since you don't care about characters outside the ANSI range, brute force would work.
std::string Utils::CString2String(const CString& cString)
{
std::string strStd;
for (int i = 0; i < cString.GetLength(); ++i)
{
if (cString[i] <= 0x7f)
strStd.append(1, static_cast<char>(cString[i]));
else
strStd.append(1, '?');
}
return strStd;
}