C++ ATL CString 到字符数组的转换

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10578522/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 14:14:33  来源:igfitidea点击:

Conversion of ATL CString to character array

c++visual-c++charc-strings

提问by Vaibhav

I want to convert a CStringinto a char[]. Some body tell me how to do this?

我想将 aCString转换为char[]. 有人告诉我如何做到这一点?

My code is like this :

我的代码是这样的:

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

回答by dutt

This seems to be along the right lines; http://msdn.microsoft.com/en-us/library/awkwbzyc.aspx

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

回答by psur

From MSDNsite:

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 is based on TCHARso if don't compile with _UNICODEit's CStringAor if you do compile with _UNICODEthen it is CStringW.

CString 基于TCHAR所以如果不使用_UNICODECStringA进行编译或者如果你使用它进行编译,_UNICODE那么它是CStringW.

In case of CStringWconversion looks little bit different (example also from MSDN):

如果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;

回答by gliderkite

You could use wcstombs_s:

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

回答by Bart?omiej Tyla

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

如果您使用 ATL,则可以使用其中一种转换宏。CString 将数据存储为 tchar,因此您将使用 CT2A()(宏名称中的 C 代表 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.

这些宏是智能的,如果 tchar 代表 ascii(没有定义 _UNICODE),它们只是传递指针而不做任何事情。

More info below, under ATL String-Conversion Classessection: http://www.369o.com/data/books/atl/index.html?page=0321159624%2Fch05.html

更多信息,在ATL 字符串转换类部分:http: //www.369o.com/data/books/atl/index.html?page=0321159624%2Fch05.html

回答by shree

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.

fopen 是需要 char* 参数的函数。所以如果你有 CString 作为可用字符串,你可以使用波纹管代码。很高兴:) 在这里,cFDlg.GetPathName().GetString();基本上在我的代码中返回 CString 。

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

回答by 123iamking

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

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

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

回答by Amir Twito

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

回答by Vinz

It's simple

这很简单

ATL CStringsallow very simple usage without having to do a lot of conversions between types. You can most easily do:

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

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

or in UNICODE environment:

或在 UNICODE 环境中:

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 static_cast(or C-Style cast) will tr​​igger the CString::operator LPCTSTR,所以你不用自己做任何指针重新解释,而是依赖ATL代码!

The documentation of this cast operator says:

这个转换运算符的文档说:

This useful casting operator provides an efficient method to access the null-terminated C stringcontained in a CStringobject. No characters are copied; only a pointer is returned.Be careful with this operator. If you change a CStringobject after you have obtained the character pointer, you may cause a reallocation of memory that invalidates the pointer.

这个有用的转换运算符提供了一种有效的方法来访问包含在CString对象中的以空字符结尾的 C 字符串不复制任何字符;只返回一个指针。小心这个运营商。如果在获得字符指针后更改CString对象,可能会导致重新分配内存,从而使指针无效。

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

正如上面的语句中提到的,转换操作符返回的指针并不意味着被修改。但是,如果您仍然需要为某些过时的 C 库使用可修改的指针,则可以使用 a 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

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.

如果你想修改指针,你不会像其他答案提到的那样将某种内存复制到可修改的内存。

回答by ANDH001

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

回答by hamstergene

CStringA/Wis cheaply and implicitly convertible to const char/wchar_t *. Whenever you need C-style string, just pass CStringobject itself (or the result of .GetString()which is the same). The pointer will stay valid as long as string object is alive and unmodified.

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

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.

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

If you have CStringWbut you need const char*and vice versa, you can use a temporary CStringAobject:

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

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.

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

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