问下关于CString类的GetLength的疑问
本帖最后由 ling1874 于 2013-01-11 14:24:43 编辑 代码如下:
TRACE("CStringTest \n");
CString str="";
UCHAR *buf=new UCHAR[1024];
str+=(UCHAR)0;
str+=(UCHAR)0x1;
str+=(UCHAR)0x31;
str+=(UCHAR)0;
str+=(UCHAR)0x99;
memcpy(buf,str.GetBuffer(str.GetLength()),str.GetLength());
for(int i=0;i<str.GetLength();i++)
{
TRACE("0x%02x ",buf[i]);
}
TRACE("\n");
运行的时候打印的信息是:
0x00 0x01 0x31 0x00 0x99
字符集是多字节字符集.
CString的GetLength不是以0作为结尾符号的吗,为何此处还是识别到5的长度呢
[解决办法]
str+=(UCHAR)0;会调用到AppendChar
void AppendChar( _In_ XCHAR ch )
{
UINT nOldLength = GetLength();
int nNewLength = nOldLength+1;
PXSTR pszBuffer = GetBuffer( nNewLength );
pszBuffer[nOldLength] = ch;
ReleaseBufferSetLength( nNewLength );
}
void ReleaseBufferSetLength( _In_ int nNewLength )
{
ATLASSERT( nNewLength >= 0 );
SetLength( nNewLength );
}
void SetLength( _In_ int nLength )
{
ATLASSERT( nLength >= 0 );
ATLASSERT( nLength <= GetData()->nAllocLength );
if( nLength < 0
[解决办法]
nLength > GetData()->nAllocLength)
AtlThrow(E_INVALIDARG);
GetData()->nDataLength = nLength;
m_pszData[nLength] = 0;
}
int GetLength() const throw()
{
return( GetData()->nDataLength );
}
可以看出当使用AppendChar的时候是直接修改记录的 字符串长度的。
调用ReleaseBuffer之后才会重新遍历一下得到长度。
[解决办法]
首先,直接写在代码里的字符串文本,编译时会将字符串内容以C风格字符串格式放在数据区,在代码里只留下指向这个区域的字符指针
所以,CString str = "abcd\n";这行代码等价于char * pTemp = "abcd\n";CString str = pTemp;
然后,去看CString的构造函数里对char*类型的重载,里面默认按C风格字符串指针处理输入参数——哪怕实际上你给的不是一个字符串指针。
顺便,CString对于char*和wchar_t*都有重载,哪个是内存复制哪个是编码转换,取决于是否定义了UNICODE宏