From the CString interface, clearly one should not assume that a CString is null-terminated. However, it seems that sometimes there is, in fact, a null character at the end of the string. Is it possible, in the Windows implementation, to create a CString that does not have a null character, so that reading one character past the e开发者_Python百科nd of the string is looking at a different heap object?
Yes, the CString is always null terminated.
The documentation states that the you can cast a CString to LPCTSTR, and LPCTSTR is a typedef to one of:
__nullterminated CONST WCHAR *
__nullterminated CONST CHAR *
depending on whether UNICODE is defined or not.
The cast to LPCTSTR
will provide a null-terminated string, but there's no guarantee that the string is null terminated before that conversion. It could easily terminate the string inside the function.
The source of CString is provided by Microsoft, the best way to make sure is to look there and see exactly how things are implemented. Of course it could always change in the next version - CString has had quite a few changes over the years.
A CString
is more like a Visual Basic string or a BSTR
. It can contain embedded binary zeros in the data portion of the CString. However when using the various operators to convert between the CString
and standard C type zero terminated strings, an embedded binary zero is treated like an end of string character. So a CString
is a lot like a BSTR
type of variable.
For instance I put the following source lines into an MFC project and ran it in the Visual Studio C++ debugger.
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
As far as going to the next heap object, I would not depend on that. It is up to the implementation of CString
as to how the object is laid out in memory and how it is using memory. It may be that if you create a CString
, a buffer sized for 64 characters is allocated regardless of how few characters you put into it. CString
provides the GetLength()
method to find out how many characters are in the CString
so that should be used. There are also methods for getting and setting specific character positions.
CString
was designed to allow the programmer to think in terms of strings as in Visual Basic types of strings rather than having to deal with C style strings that are really arrays of characters with a special end of string terminator character, the binary zero.
Edit01 - Compiler arguments and effects on CString
The Visual Studio compilers previous to Visual Studio 2013 allowed the CString
class to create either 8 bit Multi-Byte Character Set or 16 bit UNICODE character strings depending on whether _MBCS or _UNICODE was defined when processing the source file.
The reason I say previous to Visual Studio 2013 is that it appears that using _MBCS is now deprecated (see also Side-effect of deprecation of MBCS support for MFC in VS 2013).
The root of this flexibility is the TCHAR
definition which may be either char
if _MBCS is defined or wchar_t
if _UNICODE is defined. This in turn determines what happens with the _T()
or TEXT()
macro which will turn a quoted string into either an array of type char
or an array of type wchar_t
by either pre-pending or not the L
used to indicate a wchar_t
text string. This also influences the actual type of an LPCTSTR
(pointer to a const TCHAR
string) or LPTSTR
(pointer to a non-const TCHAR
string).
Windows 95/98/ME did not have native support for UNICODE in the Windows API as did Windows NT/2000/XP so allowing the choice of UNICODE to target Windows NT or MBCS to target Windows 95 was helpful. Another option at the time was the Microsoft Layer for Unicode that provided a UNICODE interface to the Windows API for Windows 95/98/ME.
Look at the MSDN documentation here:
http://msdn.microsoft.com/es-es/library/awkwbzyc(v=vs.80).aspx
Based on that I would guess there is a null terminator there you just have to do some casting to get it.
精彩评论