问下关于CString类的GetLength的疑问 本帖最后由 ling1874 于 2013-01-11 14:24:43 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 我的意思是getlength如果是真的以'\0'作为结尾的,此时的长度应该是0才对啊,为何是5呢,因为我的第一个字节就是0x00啊 自己管理内存的字符串类,都会自己记录当前字符串的长度,不看你的字符串哪个位置是0字符串以0结尾,那是C风格字符串的规定,自己管理内存的字符串类不需要遵守这个规定,当然它们一般都提供转换成C风格字符串指针的功能,std::string是c_str()函数,CString是LPCTSTR隐式转换 所以问题很简单“谁告诉你getlength是真的以'\0'作为结尾的?” CString::GetLength()的实现是这样的,不是一个一个扫描,直到_T('\0')结束的,有兴趣是去看看CString的源代码int GetLength() const throw() { return( GetData()->nDataLength ); }CStringData* GetData() const throw() { return( reinterpret_cast< CStringData* >( m_pszData )-1 ); } 如果你要计算str的长度,请用_tcslen(str); _tcslen的计算才是以'\0'结尾的。 可能是我的理解有误,那么Cstring str="abcd\0"; 的长度是4,这时候是怎么解释的呢? 我的真正用意是想将不可见字符存入CString,但是又担心0x00对求其长度有所影响 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宏 CString 兼容宽字符和MBCS字符, MFC打开并分析 midi文件,如何实现? 急!如果将GDI绘图函数转换为600DPI的位图? 程序主对话框怎么设置角上的图标啊 谁知道这个函数? 请问为什么capDriverDisconnect函数无法终止摄像头的视频捕捉? IMPLEMENT_SERIAL(CTree,CObject,0)各参数是何意思??? 动态库的问题!!!! 如何用vc调用vb编的dll 怎样判断GetKeyState的返回值 硬盘有坏块,怎么编程跳过去? 改变显示器内容 请教达人excel把文本转换为数字的问题!!比较急!!
“谁告诉你getlength是真的以'\0'作为结尾的?”
int GetLength() const throw()
{
return( GetData()->nDataLength );
}CStringData* GetData() const throw()
{
return( reinterpret_cast< CStringData* >( m_pszData )-1 );
}
可能是我的理解有误,
那么Cstring str="abcd\0"; 的长度是4,这时候是怎么解释的呢?
{
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之后才会重新遍历一下得到长度。
所以,CString str = "abcd\n";这行代码等价于char * pTemp = "abcd\n";CString str = pTemp;然后,去看CString的构造函数里对char*类型的重载,里面默认按C风格字符串指针处理输入参数——哪怕实际上你给的不是一个字符串指针。
顺便,CString对于char*和wchar_t*都有重载,哪个是内存复制哪个是编码转换,取决于是否定义了UNICODE宏