
MFC那些烦人的字符类型
烦人的类型是哪来的?
Win32和MFC编程的字符类型相当的丰(fan)富(za)。在开发过程中,如果你正好使用了别人的接口,而这些接口不是针对MFC进行开发的,那你就会陷入无限的字符类型转换套娃中。
首先要知道的是,烦人的套娃是如何产生的?——答案是类型的字节长度,举个例子:UNICODE是用两个字节表示一个字符的方法,而ASII是用一个字节表示,在UNICODE工程中 CSting 中每个字符占两个字节,就算是数字或者ASII字符一样都占两个字节,高位是用0进行填充。而我们熟知的char* 每个字符就是一个字节的。而MBCS,它是多字节字符集,用不定长表示世界文字的编码。MBCS表示英文字母时就和ASCII一样,但表示其他文字时就需要用多字节。
眼花缭乱的类型
LPSTR、LPCSTR、LPWSTR、LPTSTR这些到底是啥意思,有啥区别?
首先我们要知道啥意思:
- L:就是长~
- P:就是指针
- C:const 表明其定义的是一个常量
- T:定义了UNICODE,每字符占2字节,否则占1字节
- STR:就是字符串咯
这时候就会有同学要问,这个长指针是啥?他其实是一个很古老的概念,早期内存管理不太方便,访问某些地址时,普通的指针无法访问就需要用长指针,当然我没经历过那个时代,这里不展开了。总之现在长指针就是指针,长不长的么得关系。
MBCS宏对应的字符串指针是char*也就是LPSTR,而UNICODE宏定义的字符串指针是unsigned char*也就是LPWSTR,而LPTSTR就是一个墙头草,如果定义了UNICODE它就是LPWSTR,没定义他就是LPSTR。据说是微软为了方便写代码定义的LPTSTR(为了方便你就不能统一一下编码吗!)。
LPSTR与char*可以互换使用,
LPWSTR也可以直接用wchar_t*表示。
套娃转换开始
首先来介绍两个转换的工具:
_T()和L,在定义了UNICODE的情况下,两者均可将单字节字符串变为双字节字符串。BUT!_T()如果没有定义UNICODE就不会进行转换了,L不管你是以什么方式编译,一律UNICODE方式保存。
反过来转换有T2A、A2W等一系列乱七八糟的宏,稍微介绍一下含义:
- T:就是有T的被称为中间类型的类型
- A:ASCII
- W:宽字符串,也就是 UNICODE
- C:const
其实CString中有方法 Getbuffer()
可以直接将CString转化为char* 但是我经常遇到的一个问题就是在CString获取到一串数字文本后,费劲转为char*后,可能还需要使用C函数,将转换后的char*作为参数, 比如用atoi转换为整形时,就只剩最开头的数字了。这时候就需要使用一些技巧了。
CString temp_str = L"abc";
USES_CONVERSION;//这里是必须的
char* cstr = T2A(temp_str.GetBuffer());
int i = atoi(cstr);
还有一个方法是
char* cstr = _bstr_t(temp_str.GetBuffer());
另外, _ttoi()
这个函数可以直接将CString转换为int型。上面的复杂操作只是作为举例。
CString str = _T("123");
int n = _ttoi(str);
_bstr_t
可以构建一个BSTR,这也可以将 ANSII 字符串参数转换为UNICODE,但毕竟不是专门针对字符串转换这个需求的,还是尽量使用 T2A
或 W2A
更好一些。
