How do I convert CString into const char *? I have tried everything found on the internet but I still cant convert them.
Please help.
Thank you.
CString casts to const char * directly
CString temp;
temp = "Wow";
const char * foo = (LPCSTR) temp;
printf("%s", foo);
will print 'foo'
Newer version of MFC also support the GetString() method:
CString temp;
temp = "Wow";
const char * foo = temp.GetString();
printf("%s", foo);
Short answer: Use the CT2CA macro (see ATL and MFC String Conversion Macros). This will work regardless of your project's 'Character Set' setting.
Long answer:
If you have the UNICODE preprocessor symbol defined (i.e., if TCHAR is wchar_t), use the CT2CA or CW2CA macro.
If you don't (i.e., if TCHAR is char), CString already has an operator to convert to char const* implicitly (see CSimpleStringT::operator PCXSTR).
If your application is not Unicode, you can simple typecast to const char *. Use the GetBuffer() method if you need a char * that you can modify.
If your application is Unicode and you really want a char *, then you'll need to convert it. (You can use functions like MultiByteToWideChar().)
I know it's late, but I couldn't use the marked-as-answer solution. I search all over the internet and nothing worked for me. I muscled through it to get a solution:
char * convertToCharArr(CString str) {
int x = 0;
string s = "";
while (x < str.GetLength()) {
char c = str.GetAt(x++);
s += c;
}
char * output = (char *)calloc(str.GetLength() + 1, sizeof(char));
memcpy(output, s.c_str(), str.GetLength() + 1);
return output;
}
First : define char *inputString; in your_file.h
Second : define in yourFile.cpp :
CString MyString;
MyString = "Place here whatever you want";
inputString = new char[MyString.GetLength()];
inputString = MyString.GetBuffer(MyString.GetLength());
The last two sentences convert a CString variable to a char*; but be carefull, with CString you can hold millons of charcteres but with char* no. You have to define the size of your char* varible.
Related
As the title states I have a simple char that retrieves a full path name of a file I am looking for and I need to convert it to const wchar_t. How can I achieve this? Here is an example of the code:
int main()
{
char filename[] = "poc.png";
char fullFilename[MAX_PATH];
GetFullPathName(filename, MAX_PATH, fullFilename, nullptr);
const wchar_t *path = fullFilename;
}
As you can see I am trying to get the filename to convert but I couldn't find a way to do so. What would be the most simple solution to this?
Your code doesn't show any need to convert between char and wchar_t. Most likely you don't actually need to convert the character types. If you want to use the wchar_t-friendly GetFullPathNameW, then just use wchar_t instead of char.
int main()
{
wchar_t fullFilename[MAX_PATH];
GetFullPathNameW(L"poc.png", MAX_PATH, fullFilename, nullptr);
const wchar_t *path = fullFilename;
return 0;
}
If you really do need to convert between wchar_t-based C-style strings and char-based C-style strings, then you can use the APIs MultiByteToWideChar and WideCharToMultiByte.
I am trying to convert previous code to VS 2010. The code I am trying to convert is mentioned below. The function addCommand is defined like
addCommand(const ACHAR * cmdGroupName, const ACHAR * cmdGlobalName, const ACHAR * cmdLocalName, Adesk::Int32 commandFlags, AcRxFunctionPtr FunctionAddr,AcEdUIContext *UIContext=NULL, int fcode=-1, HINSTANCE hResourceHandle=NULL, AcEdCommand** cmdPtrRet=NULL)
The third required argument is of type ACHAR. The function is called in the following way.
char cmdLocRes[65];
// If idLocal is not -1, it's treated as an ID for
// a string stored in the resources.
if (idLocal != -1) {
// Load strings from the string table and register the command.
::LoadString(_hdllInstance, idLocal, cmdLocRes, 64);
acedRegCmds->addCommand(cmdGroup, cmdInt, cmdLocRes, cmdFlags, cmdProc);
My problem is that the variable cmdLocRes is of type char but the argument needs to be of type ACHAR.
How can I convert the same ?
ACHAR is a typedef (made by Autodesk in file AdAChar.h) of wchar_t. So the question is how to convert a char to wchar_t.
In a wider context this problem is because of the existence of unicode. Linux and Windows programmers normally discuss it without understanding each other. As I do not understand it, too, I cannot explain it. There are threads for the eager beaver: What's "wrong" with C++ wchar_t and wstrings? What are some alternatives to wide characters?
The folling might give you an idea how to convert it.
// Convert char to wchar_t
char cmdLocRes[65];
// Remark: Make sure cmdLocRes contains elements!
cmdLocRes[0] = 'A';
cmdLocRes[1] = '\0';
// Get a wstringstream
std::wstringstream str;
// Write the char array to the wstringstream
str << cmdLocRes;
// Get a wstring from the wstringstream
std::wstring wstr = str.str();
// Get a wchar_t from the wstring
const wchar_t *chr1 = wstr.c_str();
const ACHAR *chr2 = wstr.c_str(); // We see that wchar_t == ACHAR!
Better think of using wchar_t cmdLocRes[65] instead of char cmdLocRes[65]!
Sorry for the code style, but this text field is another great example for how not to do it. It took me longer to try to format the code block (and please look at it!!!) than to write the answer. Jesus!!!
I'm trying to use the function with the following declaration:
extern int stem(struct stemmer * z, char * b, int k)1
I'm trying to pass a C++ string to it, so I thought I'd use the c_str() function. It returns const char *. When I try to pass it to the stem() function, I get this error: error: invalid conversion from 'const char*' to 'char*' [-fpermissive].
How can I store the result of c_str() such that I can use it with the stem function?
Here is the code I'm running:
struct stemmer * z = create_stemmer();
char * b = s.c_str();
int res = stem(z, b, s.length()); //this doesn't work
free_stemmer(z);
return s.substr(0,res);
The problem you are having is that c_str() returns a buffer that can not be modified (const), while stem() may modify the buffer you pass in (not const). You should make a copy of the result of c_str() to get a modifiable buffer.
The page http://www.cplusplus.com/reference/string/string/c_str/ has more information on the C++ 98 and 11 versions. They suggest replacing char * b = s.c_str(); with the following:
char * b = new char [s.length()+1];
std::strcpy (b, s.c_str());
You shouldn't try to remove constness of a string returned by c_str():
char * b = s.c_str();
but you can pass an address of std::string's internal buffer directly:
int res = stem(z, static_cast<char*>(&s[0]), s.length());
If stem() is going to modify the string, then make a copy of it:
char * scpy= strdup( s.c_str()) ;
int res = stem(z, scpy, strlen( scpy));
free( scpy) ;
Use const_cast:
int res = stem(z, const_cast<char*>(s.c_str()), s.length()+1);
free_stemmer(z);
return s.substr(0,res);
Note the length+1 expression which might (or might not) be needed. C-style strings (char*) have an additional null terminator (zero byte, equivalent "\0") at the end. Your stem function may (or may not) expect a null terminator at the end of the string - try both variants.
Note also that "stem" function should not try to modify the string, otherwise bad things may happen (warning based on #David Heffernan's comment)
.c_str()
Just returns a pointer to the data, I would update the stem function to accept a 'const char*' unless you are wanting to modify the data in the string, in that case you should pass it as a new string object.
If you can't edit the stem function you can cast it:
int res = stem(z, const_cast<char*>(s.c_str()), s.length());
It's not good to do this, but nothing stops you:
#include <iostream>
#include <string>
using namespace std;
void foo(char *ch)
{
ch[0] = 'B';
}
int main()
{
string str = "helo world";
char *ch = const_cast<char *>(str.c_str());
foo(ch);
// Belo world
cout << str << endl;
return 0;
}
I want to convert a CString into a char[]. Some body tell me how to do this?
My code is like this :
CString strCamIP1 = _T("");
char g_acCameraip[16][17];
strCamIP1 = theApp.GetProfileString(strSection, _T("IP1"), NULL);
g_acCameraip[0] = strCamIP1;
This seems to be along the right lines; http://msdn.microsoft.com/en-us/library/awkwbzyc.aspx
CString aCString = "A string";
char myString[256];
strcpy(myString, (LPCTSTR)aString);
which in your case would be along the lines of
strcpy(g_acCameraip[0], (LPCTSTR)strCamIP1);
From MSDN site:
// Convert to a char* string from CStringA string
// and display the result.
CStringA origa("Hello, World!");
const size_t newsizea = (origa.GetLength() + 1);
char *nstringa = new char[newsizea];
strcpy_s(nstringa, newsizea, origa);
cout << nstringa << " (char *)" << endl;
CString is based on TCHAR so if don't compile with _UNICODE it's CStringA or if you do compile with _UNICODE then it is CStringW.
In case of CStringW conversion looks little bit different (example also from MSDN):
// Convert to a char* string from a wide character
// CStringW string. To be safe, we allocate two bytes for each
// character in the original string, including the terminating
// null.
const size_t newsizew = (origw.GetLength() + 1)*2;
char *nstringw = new char[newsizew];
size_t convertedCharsw = 0;
wcstombs_s(&convertedCharsw, nstringw, newsizew, origw, _TRUNCATE );
cout << nstringw << " (char *)" << endl;
You could use wcstombs_s:
// Convert CString to Char By Quintin Immelman.
//
CString DummyString;
// Size Can be anything, just adjust the 100 to suit.
const size_t StringSize = 100;
// The number of characters in the string can be
// less than String Size. Null terminating character added at end.
size_t CharactersConverted = 0;
char DummyToChar[StringSize];
wcstombs_s(&CharactersConverted, DummyToChar,
DummyString.GetLength()+1, DummyString,
_TRUNCATE);
//Always Enter the length as 1 greater else
//the last character is Truncated
If you are using ATL you could use one of the conversion macros. CString stores data as tchar, so you would use CT2A() (C in macro name stands for const):
CString from("text");
char* pStr = CT2A((LPCTSTR)from);
Those macros are smart, if tchar represents ascii (no _UNICODE defined), they just pass the pointer over and do nothing.
More info below, under ATL String-Conversion Classes section:
http://www.369o.com/data/books/atl/index.html?page=0321159624%2Fch05.html
CStringA/W is cheaply and implicitly convertible to const char/wchar_t *. Whenever you need C-style string, just pass CString object itself (or the result of .GetString() which is the same). The pointer will stay valid as long as string object is alive and unmodified.
strcpy(g_acCameraip[0], strCamIP1);
// OR
strcpy(g_acCameraip[0], strCamIP1.GetString());
If you need writable (non-const) buffer, use .GetBuffer() with optional maximum length argument.
If you have CStringW but you need const char* and vice versa, you can use a temporary CStringA object:
strcpy(g_acCameraip[0], CStringA(strCamIP1).GetString());
But a much better way would be to have array of CStrings. You can use them whereever you need null-terminated string, but they will also manage string's memory for you.
std::vector<CString> g_acCameraip(16);
g_acCameraip[0] = theApp.GetProfileString(strSection, _T("IP1"), NULL);
Use memcpy .
char c [25];
Cstring cstr = "123";
memcpy(c,cstr,cstr.GetLength());
Do you really have to copy the CString objects into fixed char arrays?
enum { COUNT=16 };
CString Cameraip[COUNT];
Cameraip[0] = theApp.GetProfileString(strSection, _T("IP1"), NULL);
// add more entries...
...and then - later - when accessing the entries, for example like this
for (int i=0; i<COUNT; ++i) {
someOp(Cameraip[i]); // the someOp function takes const CString&
}
...you may convert them, if needed.
fopen is the function which needs char* param. so if you have CString as available string, you can just use bellow code.
be happy :)
Here, cFDlg.GetPathName().GetString(); basically returns CString in my code.
char*pp = (char*)cFDlg.GetPathName().GetString();
FILE *fp = ::fopen(pp,"w");
CString str;
//Do something
char* pGTA = (LPTSTR)(LPCTSTR)str;//Now the cast
Just (LPTSTR)(LPCTSTR). Hope this is what you need :)
char strPass[256];
strcpy_s( strPass, CStringA(strCommand).GetString() );
It's simple
ATL CStrings allow very simple usage without having to do a lot of conversions between types. You can most easily do:
CString cs = "Test";
const char* str = static_cast<LPCTSTR>(cs);
or in UNICODE environment:
CString cs = "Test";
const wchar_t* str = static_cast<LPCTSTR>(cs);
How it works
The static_cast (or alternatively C-Style cast) will trigger the CString::operator LPCTSTR, so you don't do any pointer reinterpretation yourself but rely on ATL code!
The documentation of this cast operator says:
This useful casting operator provides an efficient method to access the null-terminated C string contained in a CString object. No characters are copied; only a pointer is returned. Be careful with this operator. If you change a CString object after you have obtained the character pointer, you may cause a reallocation of memory that invalidates the pointer.
Modifiable Pointers
As mentioned in the above statement, the returned pointer by the cast operator is not meant to be modified. However, if you still need to use a modifiable pointer for some outdated C libraries, you can use a const_cast (if you are sure that function wont modify the pointer):
void Func(char* str) // or wchar_t* in Unicode environment
{
// your code here
}
// In your calling code:
CString cs = "Test";
Func(const_cast<LPTSTR>(static_cast<LPCTSTR>(test))); // Call your function with a modifiable pointer
If you wish to modify the pointer, you wont get around doing some kind of memory copying to modifiable memory, as mentioned by other answers.
There is a hardcoded method..
CString a = L"This is CString!";
char *dest = (char *)malloc(a.GetLength() + 1);
// +1 because of NULL char
dest[a.GetLength()] = 0; // setting null char
char *q = (char *)a.m_pszData;
//Here we cannot access the private member..
//The address of "m_pszData" private member is stored in first DWORD of &a...
//Therefore..
int address = *((int *)&a);
char *q = (char *)address;
// Now we can access the private data!, This is the real magic of C
// Size of CString's characters is 16bit...
// in cstring '1' will be stored as 0x31 0x00 (Hex)
// Here we just want even indexed chars..
for(int i = 0;i<(a.GetLength()*2);i += 2)
dest[i/2] = *(q+i);
// Now we can use it..
printf("%s", dest);
I want to convert a std::string into a char* or char[] data type.
std::string str = "string";
char* chr = str;
Results in: “error: cannot convert ‘std::string’ to ‘char’ ...”.
What methods are there available to do this?
It won't automatically convert (thank god). You'll have to use the method c_str() to get the C string version.
std::string str = "string";
const char *cstr = str.c_str();
Note that it returns a const char *; you aren't allowed to change the C-style string returned by c_str(). If you want to process it you'll have to copy it first:
std::string str = "string";
char *cstr = new char[str.length() + 1];
strcpy(cstr, str.c_str());
// do stuff
delete [] cstr;
Or in modern C++:
std::vector<char> cstr(str.c_str(), str.c_str() + str.size() + 1);
More details here, and here but you can use
string str = "some string" ;
char *cstr = &str[0];
As of C++11, you can also use the str.data() member function, which returns char *
string str = "some string" ;
char *cstr = str.data();
If I'd need a mutable raw copy of a c++'s string contents, then I'd do this:
std::string str = "string";
char* chr = strdup(str.c_str());
and later:
free(chr);
So why don't I fiddle with std::vector or new[] like anyone else? Because when I need a mutable C-style raw char* string, then because I want to call C code which changes the string and C code deallocates stuff with free() and allocates with malloc() (strdup uses malloc). So if I pass my raw string to some function X written in C it might have a constraint on it's argument that it has to allocated on the heap (for example if the function might want to call realloc on the parameter). But it is highly unlikely that it would expect an argument allocated with (some user-redefined) new[]!
(This answer applies to C++98 only.)
Please, don't use a raw char*.
std::string str = "string";
std::vector<char> chars(str.c_str(), str.c_str() + str.size() + 1u);
// use &chars[0] as a char*
If you just want a C-style string representing the same content:
char const* ca = str.c_str();
If you want a C-style string with new contents, one way (given that you don't know the string size at compile-time) is dynamic allocation:
char* ca = new char[str.size()+1];
std::copy(str.begin(), str.end(), ca);
ca[str.size()] = '\0';
Don't forget to delete[] it later.
If you want a statically-allocated, limited-length array instead:
size_t const MAX = 80; // maximum number of chars
char ca[MAX] = {};
std::copy(str.begin(), (str.size() >= MAX ? str.begin() + MAX : str.end()), ca);
std::string doesn't implicitly convert to these types for the simple reason that needing to do this is usually a design smell. Make sure that you really need it.
If you definitely need a char*, the best way is probably:
vector<char> v(str.begin(), str.end());
char* ca = &v[0]; // pointer to start of vector
This would be better as a comment on bobobobo's answer, but I don't have the rep for that. It accomplishes the same thing but with better practices.
Although the other answers are useful, if you ever need to convert std::string to char* explicitly without const, const_cast is your friend.
std::string str = "string";
char* chr = const_cast<char*>(str.c_str());
Note that this will not give you a copy of the data; it will give you a pointer to the string. Thus, if you modify an element of chr, you'll modify str.
Assuming you just need a C-style string to pass as input:
std::string str = "string";
const char* chr = str.c_str();
To obtain a const char * from an std::string use the c_str() member function :
std::string str = "string";
const char* chr = str.c_str();
To obtain a non-const char * from an std::string you can use the data() member function which returns a non-const pointer since C++17 :
std::string str = "string";
char* chr = str.data();
For older versions of the language, you can use range construction to copy the string into a vector from which a non-const pointer can be obtained :
std::string str = "string";
std::vector<char> str_copy(str.c_str(), str.c_str() + str.size() + 1);
char* chr = str_copy.data();
But beware that this won't let you modify the string contained in str, only the copy's data can be changed this way. Note that it's specially important in older versions of the language to use c_str() here because back then std::string wasn't guaranteed to be null terminated until c_str() was called.
To be strictly pedantic, you cannot "convert a std::string into a char* or char[] data type."
As the other answers have shown, you can copy the content of the std::string to a char array, or make a const char* to the content of the std::string so that you can access it in a "C style".
If you're trying to change the content of the std::string, the std::string type has all of the methods to do anything you could possibly need to do to it.
If you're trying to pass it to some function which takes a char*, there's std::string::c_str().
Here is one more robust version from Protocol Buffer
char* string_as_array(string* str)
{
return str->empty() ? NULL : &*str->begin();
}
// test codes
std::string mystr("you are here");
char* pstr = string_as_array(&mystr);
cout << pstr << endl; // you are here
Conversion in OOP style
converter.hpp
class StringConverter {
public: static char * strToChar(std::string str);
};
converter.cpp
char * StringConverter::strToChar(std::string str)
{
return (char*)str.c_str();
}
usage
StringConverter::strToChar("converted string")
For completeness' sake, don't forget std::string::copy().
std::string str = "string";
const size_t MAX = 80;
char chrs[MAX];
str.copy(chrs, MAX);
std::string::copy() doesn't NUL terminate. If you need to ensure a NUL terminator for use in C string functions:
std::string str = "string";
const size_t MAX = 80;
char chrs[MAX];
memset(chrs, '\0', MAX);
str.copy(chrs, MAX-1);
You can make it using iterator.
std::string str = "string";
std::string::iterator p=str.begin();
char* chr = &(*p);
Good luck.
A safe version of orlp's char* answer using unique_ptr:
std::string str = "string";
auto cstr = std::make_unique<char[]>(str.length() + 1);
strcpy(cstr.get(), str.c_str());
char* result = strcpy((char*)malloc(str.length()+1), str.c_str());
Alternatively , you can use vectors to get a writable char* as demonstrated below;
//this handles memory manipulations and is more convenient
string str;
vector <char> writable (str.begin (), str.end) ;
writable .push_back ('\0');
char* cstring = &writable[0] //or &*writable.begin ()
//Goodluck
This will also work
std::string s;
std::cout<<"Enter the String";
std::getline(std::cin, s);
char *a=new char[s.size()+1];
a[s.size()]=0;
memcpy(a,s.c_str(),s.size());
std::cout<<a;
No body ever mentioned sprintf?
std::string s;
char * c;
sprintf(c, "%s", s.c_str());