Преобразование ATL CString в массив символов

Я хочу преобразовать CString в char[]. Кто-нибудь скажет мне, как это сделать?

Мой код такой:

CString strCamIP1 = _T("");
char g_acCameraip[16][17];
strCamIP1 = theApp.GetProfileString(strSection, _T("IP1"), NULL);
g_acCameraip[0] = strCamIP1;

person Vaibhav    schedule 14.05.2012    source источник
comment
Благодаря всем вам я решил эту проблему с помощью метода WideCharToMultiByte следующим образом: TCHAR tchCamIPTemp[15]; _tcscpy(tchCamIPTemp, strCamIP1); WideCharToMultiByte(CP_ACP, 0, tchCamIPTemp, -1, g_acCameraip[0], sizeof(g_acCameraip[0]), NULL, NULL);   -  person Vaibhav    schedule 14.05.2012


Ответы (11)


Это кажется правильным; http://msdn.microsoft.com/en-us/library/awkwbzyc.aspx

CString aCString = "A string";
char myString[256];
strcpy(myString, (LPCTSTR)aString);

который в вашем случае будет соответствовать

strcpy(g_acCameraip[0], (LPCTSTR)strCamIP1);
person dutt    schedule 14.05.2012
comment
Я получил ошибку как error C2664: 'strcpy' : cannot convert parameter 2 from 'const unsigned short *' to 'const char * - person Vaibhav; 14.05.2012
comment
опечатка: \CString aCString = строка; char myString[256]; strcpy(myString, (LPCTSTR)aString); - person ingconti; 06.06.2015
comment
Имо это лучший и самый простой способ сделать это. Если вы хотите использовать приведения C++, вы можете сделать static_cast<LPCTSTR>(cstringVar), и он будет работать в Unicode и MBCS. - person Vinz; 19.10.2016
comment
Это не удается на 1-й строке: не существует подходящего конструктора для преобразования из const char [9] в ATL::CStringT‹wchar_t, StrTraitMFC‹wchar_t, ATL::ChTraitsCRT‹wchar_t››› - person Igor Meszaros; 08.11.2017

С сайта MSDN:

// 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 основан на TCHAR, поэтому, если не компилировать с _UNICODE, это CStringA, а если компилировать с _UNICODE, то это CStringW.

В случае CStringW преобразование выглядит немного иначе (пример также из 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;
person psur    schedule 14.05.2012
comment
подойдет ли origw.GetLength() * 2 +1? - person user734028; 18.07.2014

Вы можете использовать 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
person gliderkite    schedule 14.05.2012

Если вы используете ATL, вы можете использовать один из макросов преобразования. CString хранит данные как tchar, поэтому вы должны использовать CT2A() (C в имени макроса означает const):

CString from("text");

char* pStr = CT2A((LPCTSTR)from);

Эти макросы умны, если tchar представляет ascii (не определено _UNICODE), они просто передают указатель и ничего не делают.

Подробнее см. ниже в разделе Классы преобразования строк ATL: http://www.369o.com/data/books/atl/index.html?page=0321159624%2Fch05.html

person Bartłomiej Tyla    schedule 28.09.2014
comment
Мне нравится это: CString from("text"); CT2A pStr(from); - person darda; 24.05.2015

CStringA/W дешево и неявно конвертируется в const char/wchar_t *. Всякий раз, когда вам нужна строка в стиле C, просто передайте сам объект CString (или результат .GetString(), что то же самое). Указатель будет оставаться действительным, пока строковый объект жив и не изменен.

strcpy(g_acCameraip[0], strCamIP1);
// OR
strcpy(g_acCameraip[0], strCamIP1.GetString());

Если вам нужен перезаписываемый (неконстантный) буфер, используйте .GetBuffer() с необязательным аргументом максимальной длины.

Если у вас есть CStringW, но вам нужен const char* и наоборот, вы можете использовать временный объект CStringA:

strcpy(g_acCameraip[0], CStringA(strCamIP1).GetString());

Но гораздо лучше было бы иметь массив CStrings. Вы можете использовать их везде, где вам нужна строка с завершающим нулем, но они также будут управлять памятью строки для вас.

std::vector<CString> g_acCameraip(16);
g_acCameraip[0] = theApp.GetProfileString(strSection, _T("IP1"), NULL);
person hamstergene    schedule 14.05.2012

Используйте memcpy.

char c [25];
Cstring cstr = "123";
memcpy(c,cstr,cstr.GetLength());
person anuj.juthani    schedule 15.03.2013

Вам действительно нужно копировать объекты CString в фиксированные массивы char?

enum { COUNT=16 };
CString Cameraip[COUNT];
Cameraip[0] = theApp.GetProfileString(strSection, _T("IP1"), NULL);
// add more entries...

...а потом - позже - при доступе к записям, например вот так

for (int i=0; i<COUNT; ++i) {
    someOp(Cameraip[i]); // the someOp function takes const CString&
}

... вы можете преобразовать их, если это необходимо.

person Wolf    schedule 13.02.2014

fopen — это функция, которой нужен параметр char*. поэтому, если у вас есть CString в качестве доступной строки, вы можете просто использовать приведенный ниже код. будь счастлив :) Здесь cFDlg.GetPathName().GetString(); в основном возвращает CString в моем коде.

char*pp  = (char*)cFDlg.GetPathName().GetString();
FILE *fp = ::fopen(pp,"w");
person shree    schedule 11.08.2015

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

Просто (LPTSTR)(LPCTSTR). Надеюсь, это то, что вам нужно :)

person 123iamking    schedule 01.04.2016

Это просто

строки ATL CString обеспечивают очень простое использование без делать много преобразований между типами. Вы можете легко сделать:

CString cs = "Test";
const char* str = static_cast<LPCTSTR>(cs);

или в среде UNICODE:

CString cs = "Test";
const wchar_t* str = static_cast<LPCTSTR>(cs);

Как это работает

static_cast (или, альтернативно, C-стиль) вызовет CString::operator LPCTSTR, так что вы не будете самостоятельно переинтерпретировать указатель но полагайтесь на код ATL!

В документации этого оператора приведения говорится:

Этот полезный оператор приведения обеспечивает эффективный метод доступа к строке C с завершающим нулем, содержащейся в объекте CString. Никакие символы не копируются; возвращается только указатель. Будьте осторожны с этим оператором. Если вы измените объект CString после получения указателя на символ, вы можете вызвать перераспределение памяти, которое сделает указатель недействительным.

Модифицируемые указатели

Как упоминалось в приведенном выше заявлении, возвращаемый оператором приведения указатель не предназначен для изменения. Однако, если вам по-прежнему необходимо использовать модифицируемый указатель для некоторых устаревших библиотек C, вы можете использовать const_cast (если вы уверены, что функция не изменит указатель):

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

Если вы хотите изменить указатель, вам не удастся выполнить какое-либо копирование памяти в изменяемую память, как упоминалось в других ответах.

person Vinz    schedule 19.10.2016

Есть хардкодный метод..

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

person ANDH001    schedule 17.09.2018