问下关于CString类的GetLength的疑问

ling1874 2013-01-11 02:18:35
代码如下:

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的长度呢
...全文
419 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
lm_whales 2013-02-28
  • 打赏
  • 举报
回复
CString 兼容宽字符和MBCS字符,
kgzhw 2013-01-14
  • 打赏
  • 举报
回复
10解释的比较清晰
sddahu 2013-01-12
  • 打赏
  • 举报
回复
真心看不懂啊。要学习的地方太多了!
baichi4141 2013-01-12
  • 打赏
  • 举报
回复
引用 8 楼 ling1874 的回复:
可能是我的理解有误, 那么Cstring str="abcd\0"; 的长度是4,这时候是怎么解释的呢?
首先,直接写在代码里的字符串文本,编译时会将字符串内容以C风格字符串格式放在数据区,在代码里只留下指向这个区域的字符指针 所以,CString str = "abcd\n";这行代码等价于char * pTemp = "abcd\n";CString str = pTemp; 然后,去看CString的构造函数里对char*类型的重载,里面默认按C风格字符串指针处理输入参数——哪怕实际上你给的不是一个字符串指针。 顺便,CString对于char*和wchar_t*都有重载,哪个是内存复制哪个是编码转换,取决于是否定义了UNICODE宏
coohai 2013-01-11
  • 打赏
  • 举报
回复
10楼就是正解
  • 打赏
  • 举报
回复
引用 楼主 ling1874 的回复:
本帖最后由 ling1874 于 2013-01-11 14:24:43 编辑 代码如下: C/C++ code?123456789101112131415 TRACE("CStringTest \n"); CString str=""; UCHAR *buf=new UCHAR[1024]; str+=(……
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之后才会重新遍历一下得到长度。
ling1874 2013-01-11
  • 打赏
  • 举报
回复
我的真正用意是想将不可见字符存入CString,但是又担心0x00对求其长度有所影响
ling1874 2013-01-11
  • 打赏
  • 举报
回复
引用 5 楼 baichi4141 的回复:
所以问题很简单 “谁告诉你getlength是真的以'\0'作为结尾的?”
可能是我的理解有误, 那么Cstring str="abcd\0"; 的长度是4,这时候是怎么解释的呢?
Eleven 2013-01-11
  • 打赏
  • 举报
回复
如果你要计算str的长度,请用_tcslen(str); _tcslen的计算才是以'\0'结尾的。
Eleven 2013-01-11
  • 打赏
  • 举报
回复
CString::GetLength()的实现是这样的,不是一个一个扫描,直到_T('\0')结束的,有兴趣是去看看CString的源代码
int GetLength() const throw()
	{
		return( GetData()->nDataLength );
	}

CStringData* GetData() const throw()
	{
		return( reinterpret_cast< CStringData* >( m_pszData )-1 );
	}
baichi4141 2013-01-11
  • 打赏
  • 举报
回复
所以问题很简单 “谁告诉你getlength是真的以'\0'作为结尾的?”
baichi4141 2013-01-11
  • 打赏
  • 举报
回复
自己管理内存的字符串类,都会自己记录当前字符串的长度,不看你的字符串哪个位置是0 字符串以0结尾,那是C风格字符串的规定,自己管理内存的字符串类不需要遵守这个规定,当然它们一般都提供转换成C风格字符串指针的功能,std::string是c_str()函数,CString是LPCTSTR隐式转换
ling1874 2013-01-11
  • 打赏
  • 举报
回复
我的意思是getlength如果是真的以'\0'作为结尾的,此时的长度应该是0才对啊,为何是5呢,因为我的第一个字节就是0x00啊
静c心 2013-01-11
  • 打赏
  • 举报
回复
getlength不包括/0
jiuzhoulh 2013-01-11
  • 打赏
  • 举报
回复
楼主的代码在VC6中执行是没有问题的啊

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧