Conversion of ATL CString to character array

2019-02-18 00:09发布

问题:

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;

回答1:

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);


回答2:

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;


回答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


回答4:

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



回答5:

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);


回答6:

Use memcpy .

char c [25];
Cstring cstr = "123";
memcpy(c,cstr,cstr.GetLength());


回答7:

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.



回答8:

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");


回答9:

    CString str;
    //Do something
    char* pGTA = (LPTSTR)(LPCTSTR)str;//Now the cast

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



回答10:

char strPass[256];
strcpy_s( strPass, CStringA(strCommand).GetString() );


回答11:

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.



回答12:

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);