从CString接口,显然不应该假设CString是以null结尾的。但是,似乎有时事实上,字符串末尾有一个空字符。 在Windows实现中,是否有可能创建一个不具有空字符的CString,以便读取超出字符串末尾的一个字符正在查看不同的堆对象?
答案 0 :(得分:1)
CString
更像是Visual Basic字符串或BSTR
。它可以在CString的数据部分中包含嵌入的二进制零。但是,当使用各种运算符在CString
和标准C类型零终止字符串之间进行转换时,嵌入的二进制零被视为字符串结尾字符。因此,CString
很像BSTR
类型的变量。
例如,我将以下源代码行放入MFC项目并在Visual Studio C ++调试器中运行。
CString myString (_T("this\000is a String.")); // myString will only contain "this" as a zero terminated string.
CString myJJ;
myJJ.Format (_T("this%cisaxxx"), 0); // this creates a string with an embedded binary zero in it.
int iLen = myJJ.GetLength(); // this returns the length of the complete string, 11 characters
CString myRight = myJJ.Right(4); // this returns the right most 4 characters, "axxx"
TCHAR myTbuff[64];
_tcscpy (myTbuff, myJJ); // this copies the string up to the embedded binary zero into myTbuff
至于下一个堆对象,我不会依赖它。关于如何在内存中布置对象以及如何使用内存,由CString
实现。可能是如果您创建CString
,则会分配一个大小为64个字符的缓冲区,而不管您放入的字符数是多少。 CString
提供了GetLength()
方法,可以找出CString
中应该使用的字符数。还有获取和设置特定角色位置的方法。
CString
旨在允许程序员在字符串方面考虑字符串的Visual Basic类型,而不是必须处理C样式字符串,这些字符串实际上是字符串数组,具有字符串终止符的特殊结尾,二进制零。
Edit01 - 编译器参数和对CString的影响
Visual Studio 2013之前的Visual Studio编译器允许CString
类创建8位多字节字符集或16位UNICODE字符串,具体取决于在处理源文件时是否定义了_MBCS或_UNICODE。
我在Visual Studio 2013之前说的原因是,现在不推荐使用_MBCS(另请参阅Side-effect of deprecation of MBCS support for MFC in VS 2013)。
此灵活性的根源是TCHAR
定义,如果定义了_MBCS,则可以是char
,如果定义了_UNICODE,则可以是wchar_t
。_T()
这反过来决定了TEXT()
或char
宏会发生什么,它会将带引号的字符串转换为类型为wchar_t
的数组或类型为L
的数组。是否使用wchar_t
来表示LPCTSTR
文本字符串。这也会影响TCHAR
(指向const LPTSTR
字符串的指针)或TCHAR
(指向非const {{1}}字符串的指针)的实际类型。
答案 1 :(得分:0)
请查看MSDN文档:
http://msdn.microsoft.com/es-es/library/awkwbzyc(v=vs.80).aspx
根据我的想法,我猜有一个空的终结符,你只需要做一些转换来获得它。
答案 2 :(得分:0)
是的,CString始终为空终止。
文档说明您可以将CString转换为LPCTSTR,而LPCTSTR是以下类型之一的typedef:
__nullterminated CONST WCHAR *
__nullterminated CONST CHAR *
取决于UNICODE是否已定义。
答案 3 :(得分:0)
转换为LPCTSTR
将提供以null结尾的字符串,但不保证字符串在转换之前为空终止。它可以轻松地终止函数内的字符串。
CString的源代码由Microsoft提供,确保最好的方法是查看并确切了解如何实现。当然,它可能会在下一个版本中发生变化 - 多年来CString已经发生了很多变化。