将 ATL CString 转换为字符数组

Conversion of ATL CString to character array

本文关键字:字符 数组 转换 ATL CString      更新时间:2023-10-16

我想将CString转换为char[]。有人告诉我该怎么做?

我的代码是这样的:

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

似乎是正确的路线; 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);

从 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;
您可以使用

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

如果您使用的是 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

CStringA/W可以廉价且隐式地转换为const char/wchar_t *。每当你需要 C 风格的字符串时,只需传递对象本身(或相同的.GetString()结果CString(。只要字符串对象处于活动状态且未修改,指针就会保持有效。

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

如果需要可写(非常量(缓冲区,请使用带有可选最大长度参数的.GetBuffer()

如果您有CStringW但需要const char*反之亦然,则可以使用临时CStringA对象:

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

但更好的方法是拥有CString数组。您可以在任何需要以 null 结尾的字符串的地方使用它们,但它们也会为您管理字符串的内存。

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

使用 memcpy .

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

真的必须将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&
}

如果需要,您可以转换它们。

>fopen 是需要 char* 参数的函数。 因此,如果您有 CString 作为可用字符串,则可以使用下面的代码。快乐:)在这里,cFDlg.GetPathName().GetString();基本上在我的代码中返回 CString。

char*pp  = (char*)cFDlg.GetPathName().GetString();
FILE *fp = ::fopen(pp,"w");
    CString str;
    //Do something
    char* pGTA = (LPTSTR)(LPCTSTR)str;//Now the cast

只是(LPTSTR((LPCTSTR(。希望这是你需要的:)

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

很简单

ATL CStrings 允许非常简单的使用,而无需在类型之间进行大量转换。您可以最轻松地执行以下操作:

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代码!

该演员操作员的文档说:

这个有用的强制转换运算符提供了一种有效的方法来访问 CString 对象中包含的以 null 结尾的 C 字符串不复制任何字符;只返回一个指针。小心这个运算符。如果在获取字符指针后更改 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

如果你想修改指针,你不会绕过对可修改的内存进行某种内存复制,正如其他答案所提到的。

有一个硬编码的方法。

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