编程中天天接触字符串,遇到无数问题之后我意识到在MFC中字符串这个东西要比我想像复杂的多,偏偏还是个必需品,想想还是一次搞清以绝后患吧……
实践中字符串主要会涉及到字符集的兼容,不同字符串类型之间的转换的问题,本文即针对此两点。
先从字符集的角度看字符和字符串
上个表:C++对字符集的支持
C++字符类型 | 字符集种类 | 字符集 |
wchar_t | 宽字符 | Unicode |
char | 多字节MBCS | ANSI |
char | 单字节SBCS | ASCII |
在MFC编程中我们见到的字符类型表示常是这几个宏定义TCHAR,CHAR,WCHAR。
从字符集角度来看CHAR等同于char,WCHAR等同于wchar_t,TCHAR会根据项目所用字符集在前两者间自动转换。同理,在VC++编程中常能见到带T,A,W字母的类型、宏或函数命名,它们的区别也一样。如表:
宽字符(Wide) | CStringW | L‘char’ | L”str” | …… |
多字节(ANSI) | CStringA | ‘char’ | “str” | …… |
自转换(Translate) | CString | _T(‘char’) | _T(“str”) | …… |
注:T的来源在MSDN上没找到,Translate无依据,自己YY出来助记的,欢迎更正或优化。
那到底字符集对编程有什么影响呢。在项目属性里有字符集的选项,这个选项会定义宏_MBCS或_UNICODE(MSDN说的,我在项目中没找到,只在WinNT.h中找到以UNICODE为条件对字符(串)的定义),它本身并不会导致程序出错,但是自转换的那些字符(串)发生了改变,当不同字符集的字符(串)之间赋值(或其它沟通)时就会提示不能转换的错误。所以说,如果程序中的字符(串)都是自转换的,那项目字符集设置就随意了。
再看各式各样让人头疼的字符串
msdn上的一句话:可以转换的字符串类型包括char*、wchar_t*、_bstr_t、CComBSTR、CString、basic_string、和String。VC++中的字符串真是多啊,有一些是跟COM编程相关的,String是.Net的类型(需开启clr支持),本文只讨论mfc。其实在mfc中从结构角度看主要就3种字符串:
C风格字符串 | 字符数组 | LPCSTR,LPCTSTR等 |
|
C++标准字符串 | basic_string模版类 | string,wstring | #include <string> |
MFC封装字符串 | CStringT模版类 | CSting,CStringA,CStringW | #include “afxstr.h” |
综合字符集和结构的角度字符串有这些
| 宽字符 | 多字节 | 自转换 |
C风格 | LPCWSTR | LPCSTR | LPCTSTR |
C++标准 | wstring | string |
|
MFC封装 | CStringW | CStringA | CString |
附:字符串常量(实际也是C风格的) | L“example” | “example” | _T(“example”) |
结构的角度 各字符串间转换
LPCTSTR arrStr = _T("hello");
CString mfcStr = _T("hello");
string stdStr = _T("hello");
//const char* 源
CString mfcFrmArr = arrStr;
string stdFrmArr = arrStr;
//CString 源
string stdFrmMfc = mfcStr;
LPCTSTR arrFrmMfc = (LPCTSTR)mfcStr;
//string 源
LPCTSTR arrFrmStd = stdStr.c_str();
CString mfcFrmStd = stdStr.c_str();
在转换时一定要保持字符集的一致,否则报错不能转换,上面代码中,除了string类型不能自动转换字符集,其它都会随项目字符集设置自动转换。上面代码适用于多字节项目,要适用于宽字符项目仅需将string换成wstring。
附:
一些类型、宏或函数命名中的特定字母意义
L:long
P:point
C:const
T:translate
A:ANSI
W:wide
结束:
本文仅是针对实用的一部分归纳,关于VC++的字符(串)的东西实在太多太复杂了。更全面的字符串间转换:
https://msdn.microsoft.com/zh-cn/library/ms235631.aspx
这个写得很真实很详细,然而我总觉得它不太实用……更适合深入了解。
水平有限,欢迎拍砖,共同进步