Conversion of ATL CString to character array
Asked Answered
T

12

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;
Tansy answered 14/5, 2012 at 6:43 Comment(1)
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);Tansy
M
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);
Millar answered 14/5, 2012 at 6:49 Comment(4)
I got an error as error C2664: 'strcpy' : cannot convert parameter 2 from 'const unsigned short *' to 'const char *Tansy
mistype: \CString aCString = "A string"; char myString[256]; strcpy(myString, (LPCTSTR)aString);Coincident
Imo this is the best and most simple way of doing it. If you wish to use C++ casts you can do static_cast<LPCTSTR>(cstringVar) and it will work under unicode and MBCS.Frontlet
This fails on the 1st line: no suitable constructor exists to convert from "const char [9]" to "ATL::CStringT<wchar_t, StrTraitMFC<wchar_t, ATL::ChTraitsCRT<wchar_t>>>Bristol
E
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;
Expressionism answered 14/5, 2012 at 6:49 Comment(1)
would origw.GetLength() * 2 +1 be fine too?Bilge
T
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
Tatia answered 14/5, 2012 at 6:48 Comment(0)
H
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

Haslett answered 28/9, 2014 at 20:46 Comment(1)
I like this: CString from("text"); CT2A pStr(from);Rickety
K
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);
Katykatya answered 14/5, 2012 at 6:58 Comment(0)
F
0

Use memcpy .

char c [25];
Cstring cstr = "123";
memcpy(c,cstr,cstr.GetLength());
Footworn answered 15/3, 2013 at 5:40 Comment(0)
A
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.

Arrester answered 13/2, 2014 at 11:12 Comment(0)
B
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");
Bor answered 11/8, 2015 at 12:6 Comment(0)
J
0
    CString str;
    //Do something
    char* pGTA = (LPTSTR)(LPCTSTR)str;//Now the cast

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

Jazmin answered 1/4, 2016 at 14:26 Comment(0)
C
0
char strPass[256];
strcpy_s( strPass, CStringA(strCommand).GetString() );
Clamshell answered 21/7, 2016 at 11:4 Comment(0)
F
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.

Frontlet answered 19/10, 2016 at 21:29 Comment(0)
C
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);
Carlton answered 17/9, 2018 at 10:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.