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
Conversion of ATL CString to character array
提问by Vaibhav
回答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 TCHAR
so if don't compile with _UNICODE
it's CStringA
or if you do compile with _UNICODE
then it is CStringW
.
CString 基于TCHAR
所以如果不使用_UNICODE
它CStringA
进行编译或者如果你使用它进行编译,_UNICODE
那么它是CStringW
.
In case of CStringW
conversion 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 trigger 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/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.
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 CStringW
but you need const char*
and vice versa, you can use a temporary CStringA
object:
如果你有CStringW
但你需要const char*
,反之亦然,你可以使用一个临时CStringA
对象:
strcpy(g_acCameraip[0], CStringA(strCamIP1).GetString());
But a much better way would be to have array of CString
s. You can use them whereever you need null-terminated string, but they will also manage string's memory for you.
但更好的方法是拥有CString
s数组。您可以在需要以空字符结尾的字符串的任何地方使用它们,但它们也会为您管理字符串的内存。
std::vector<CString> g_acCameraip(16);
g_acCameraip[0] = theApp.GetProfileString(strSection, _T("IP1"), NULL);