在网络编程中,经常用到一些参数为Multibyte字符串为参数的函数。如果编程环境是在UNICODE字符下,就要频繁涉及到UNICODE字符串与Multibyte字符串之间的转换问题。处理不当,字符串就不能正常显示,出现很多乱码,让人头疼!
近日在参照书籍用WSASOCKET模仿聊天室的编程中,就遇到这个头疼的问题。特别是当把编程环境设为UNICODE字符集后,更是连程序都没有办法启动了。经过不断思考和探索,发现:字符串转换的过程中,确定字符串所占空间(字节)大小是问题的关键。所以,为了解决这个难题,我首先去寻找双字节字符串和单字节字符串所占的空间的字节大小的规律。
一、双字节与单字节的区别:
字符串的空间大小,判断的关键是字符串的结束标志:'\0',即空字符。正常情况下,字符串的结尾都应该有结尾标志,除非自己创建的字符数组时没有手动加上。没有空字符为结尾标志的情况属非正常的情况,本文不予考虑。那么,双字节的字符串,其空间怎么计算呢?
如果字符串存储在CString对象中,使用函数GetLength()得到的大小是否是所占空间的字节数呢?
CString s,str;
s = _T("字符串123");
str.Format(_T("%d"), s.GetLength());
MessageBox(str);
上面这几句代码,字符串长度等于多少呢?正确答案是:6。
它代表的是存储的字符串的字符数!请注意:是字符数!不是字节数!
而实际上,存储这6个字符的所需空间,无论在UNICODE环境下还是多字节的环境下都不止这些。双字节按每个字符2个字节存储,即上面所需空间应该为6*2=12字节。由于要加上空字符为结尾标志,所以实际空间最后应该为14字节。
可以得出结论:UNICODE环境下,字符串的空间大小=(字符数+1)*2字节。
下面的代码更能直观反映其所占空间大小:
TCHAR buf[]= _T("字符串123");
str.Format(_T("%d"), sizeof(buf));
MessageBox(str);
结果是14字节!包括了空字符。
但有时候编程是经常要以CString为存储字符串的媒介,是否可以这样找到其存储的空间大小呢?
s = _T("字符串123");
TCHAR *pbuf = s.GetBuffer();
str.Format(_T("%d"), sizeof(pbuf));
MessageBox(str);
结果失望令人失望:答案是4!
其实仔细一看就明白,由于pbuf代表的是一个指针而已,它的大小当然一个指针的空间。不同的机器存储指针的空间大小可能不一样,但结果都指的是指针变量本身的存储的空间。
所以,双字节字符串的字节大小还是只有根据:(字符长度+1)*2来确定。当然,如果是一个字符数组,则可能直接通过sizeof得到其字节大小(包括空字符)。
现在讨论单字节的字符串的空间如何计算。这个相对简单多了。因为我们知道,单字节的字符串,是以一个字节为单位读取的。一个字节会被当作一个字符!
下面是在多字节的环境下测试:
还是从CString开始讨论:
CString s,str;
s = _T("字符串123");
str.Format(_T("%d"), s.GetLength());
MessageBox(str);
以上代码,结果显示字符串的长度应该是多少呢?答案不是6,而是9!!!
CString在不同的字符编码环境下会呈现对应的变化:UNICODE环境下,对应双字节编码;多字节环境下,会对应单字节编码。所以同样的代码,得到的字符长度不一样。
同样地,以下代码也无法得到字符串的长度:
s = _T("字符串123");
char *pbuf = s.GetBuffer();
str.Format(_T("%d"), sizeof(pbuf));
MessageBox(str);
答案不是9,而是4!!!是指针变量本身的空间大小!
同样地,是字符数组时,可以直接得到其空间大小:
char buf[]= _T("字符串123");
str.Format(_T("%d"), sizeof(buf));
MessageBox(str);
答案是10个字节!包括了空字符。为什么是10个字节,而不是7呢?因为多字节环境下,不同的字符存储的空间不一样:双字节字符仍按两个字节存储,单字节字符则按1个字节存储。上面汉字为”三个“,应占6个字节,三个数字各占1个字节,总共9个字节,加上空字符,最后总共是10个字节。
可以得出结论:在多字节环境下,一些函数得到的字符串长度(单字节的)实际上是所有字符所占的空间大小,即字节数(不包括空字符)。而UNICODE环境下,字符串长度则是指实际的字符数(不包括空字符),而不是字节数。
同时要注意:GetLength()之类的函数与sizeof运算符是不同的。后者针对是对象所占的空间字节。
进一步得到结论:
UNICODE环境下,字符串的空间大小字节数=(字符数+1)*2;
多字节环境下,字符串的空间大小字节数=字符的字数节+1 。(字符字节数通常是通过字符长度得到的)
网络编程中:UNICODE字符串与Multibyte字符串之间的转换问题
最新推荐文章于 2021-02-20 12:17:37 发布