编程基础知识——VS里面的各种字符串

来源:互联网 发布:大数据预测美国大选 编辑:程序博客网 时间:2024/06/01 18:38

在C++编程中,可能遇到的字符串的种类实在是太多了,只有清楚每一种的实现原理,并熟记一些转换函数就能够在实际开发中灵活应用。

常见的字符串类型:

1、  基本类型,C风格:char*const char*wchar_tconst wchar_t*(在早期的VS中可能以unsignedshort表示UNICODE),以及windows中常用的宏定义CHAR*TCHAR*WCHAR*LPSTRLPTSTRLPWSTRLPCSTRLPCTSTRLPCWSTR

2、  字符串封装类,C++风格:CString(根据工程设置自动转换为CStringACStringW)CAtlString(ATL工程中的CString形式,也分CAtlStringACAtlStringW)

3、  COM平台下的字符串表示:BSTRCComBSTR_bstr_t

4、  跨平台标准C++字符串stl::string/wstring

 

个人觉得,虽然类型这么多,但是其实只需要掌握三种基本的类型一切都简单了。三种基本类型就是LPSTR,LPWSTR和BSTR。

先说LPSTR,它是char* 的宏定义,最普的一种类型。注意,它并不一定是ASCII的,在微软的windows系统中,它可能是GBK的,也可能是UTF-8的。

再说LPWSTR,它是wchar_t*的宏定义,也是很普通的类型,它一定是UNICODE的。

最后是BSTR,它相对复杂一点。BSTR是UNICODE的,但是它却和LPWSTR完全一样。

BSTR和LPWSTR的区别:BSTR的字符串首字符的前面,还有四个字节,它是用来描述字符串长度的。

 

LPWSTR字符串的内存形式(以L”123”为例)

1

0

2

0

3

0

0

0

N/A

N/A

一个字符占两个字节,但因为是ASCII字符,所以第2个字节为0。最后有2个字节组成一个wchar_t形式的 ‘\0’表示结束,LPWSTR变量里存的是1所在的字节的地址

 

BSTR字符串的内存形式(以L”123”为例)

3

0

0

0

1

0

2

0

3

0

0

0

N/A

N/A

N/A

N/A

同样,一个字符占两个字节,每个字符的第二个字节为0,最后有零结束标志,BSTR变量里存的是1所在字节的地址。但是实际上BSTR使用的内存段还包括1前面的四个字节。这四个字节所代表的数字刚好是字符串的长度。

代码验证上面结论:


调试运行时查看buf1和buf2的结果:


LPWSTR与LPSTR之间的转换,如果不涉及编码问题,数据来源和使用都是在本系统中,那一般用W2A,A2W。如果使用了TCHAR,那就用T2A,A2T,T2W,W2T等宏进行转换(这种转换都是使用系统默认的编码,一般是GBK)。如果涉及到编码,比如你的系统在和别的系统打交到,可能字符串穿过来是UTF-8编码的多字节字符串,那就要使用MultiByteToWideCharWideCharToMultiByte这两个函数进行转换了。

LPWSTR和BSTR的转换:

LPWSTR –>BSTR:         BSTR  pBstr = SysAllocString(LPWSTR);

BSTR->LPWSTR:                 从技术上讲,LPWSTR pwstr =(LPWSTR)pBstr 是行得通的,但是这样代码的逻辑独立性就不够强。应该用LPWSTR pwstr  =wcscpy((LPWSTR)pBstr);这样保证BSTR和LPWSTR是独立的字符串。要独立的原因是因为BSTR和LPWSTR本身属于不同的体系,释放内存的方式也不一样。前者是SysFreeString,后者用delete。

LPSTR和BSTR的转换:用_com_util::ConvertBSTRToString()和_com_util::ConvertStringToBSTR()

至于那些封装类,比如CString,CComBSTR,就好理解了。它们只是封装了一个LPTSTR和BSTR作为成员变量,并加了一些操作的函数而已。

在使用LPCTSTR的地方,可以直接用CString作为参数,因为它有隐式转换成LPCTSTR的运算符重载。

0 0