5

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;
Vinz
  • 3,030
  • 4
  • 31
  • 52
Vaibhav
  • 69
  • 1
  • 2
  • 4
  • Thanks to all of you I solved this with the help of WideCharToMultiByte method in the following way: **TCHAR tchCamIPTemp[15]; _tcscpy(tchCamIPTemp, strCamIP1); WideCharToMultiByte(CP_ACP, 0, tchCamIPTemp, -1, g_acCameraip[0], sizeof(g_acCameraip[0]), NULL, NULL);** – Vaibhav May 14 '12 at 12:24

12 Answers12

9

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);
dutt
  • 7,909
  • 11
  • 52
  • 85
  • 5
    I got an error as `error C2664: 'strcpy' : cannot convert parameter 2 from 'const unsigned short *' to 'const char *` – Vaibhav May 14 '12 at 06:54
  • mistype: \CString aCString = "A string"; char myString[256]; strcpy(myString, (LPCTSTR)aString); – ingconti Jun 06 '15 at 13:07
  • Imo this is the best and most simple way of doing it. If you wish to use C++ casts you can do `static_cast(cstringVar)` and it will work under unicode and MBCS. – Vinz Oct 19 '16 at 19:51
  • This fails on the 1st line: no suitable constructor exists to convert from "const char [9]" to "ATL::CStringT>> – Igor Meszaros Nov 08 '17 at 15:02
7

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;
psur
  • 4,400
  • 26
  • 36
3

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
gliderkite
  • 8,828
  • 6
  • 44
  • 80
3

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

0

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);
hamstergene
  • 24,039
  • 5
  • 57
  • 72
0

Use memcpy .

char c [25];
Cstring cstr = "123";
memcpy(c,cstr,cstr.GetLength());
Royston Pinto
  • 6,681
  • 2
  • 28
  • 46
0

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.

Wolf
  • 9,679
  • 7
  • 62
  • 108
0

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");
Lachezar
  • 6,523
  • 3
  • 33
  • 34
shree
  • 1
  • 2
0
    CString str;
    //Do something
    char* pGTA = (LPTSTR)(LPCTSTR)str;//Now the cast

Just (LPTSTR)(LPCTSTR). Hope this is what you need :)

123iamking
  • 2,387
  • 4
  • 36
  • 56
0
char strPass[256];
strcpy_s( strPass, CStringA(strCommand).GetString() );
Amir Touitou
  • 3,141
  • 1
  • 35
  • 31
0

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.

Vinz
  • 3,030
  • 4
  • 31
  • 52
0

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);
ANDH001
  • 1
  • 1