一直在努力
分类:
2010-08-30 20:08:28
在MFC中CString是字符串的常用表示方法,但是还有很多别的类型,例如数字类型等。(PS:微软的人真是不容易,折腾出这么多种类型来。。。) ==================================基础知识===================================== 这一部分肯定是要首先知道什么叫“单字节字符”、“宽字符”和“多字节字符”。 参见: 所以“单字节字符”=ANSI “宽字符”= UNICODE 多字节字符往往在实际中叫做“multi-byte”。 ============================================================================== 【CString】 CString实质上是一个TCHAR类型的容器,如下: typedef ATL::CStringT< TCHAR, StrTraitMFC_DLL< TCHAR > > CString; 而TCHAR类型在Unicode环境下被定义为WCHAR,非如下: #ifdef UNICODE typedef wchar_t TCHAR; #else typedef unsigned char TCHAR; #endif wchar_t是Unicode用的宽字符类型,用双字表示的字符。 也就是说虽然CString基于TCHAR这个定义是固定的,但是由于TCHAR在不同环境下所代表的不一样,所以也就导致CString具有一定的灵活性。所以在用CString编程的时候一定要注意其是否是Unicode环境下。 =================================CString转数字================================= 下面以数字中的ULONGLONG型为例。int整型仅需要更改格式化字符串即可。 【CString转ULONGLONG】 我们记得,从标准输入读入数据的C函数是scanf(),那从字符串读取数据的函数就是sscanf()。可以参见相应的百度百科词条()。其Unicode版本就是swscanf(),这个函数在VC2008中也等价于_stscanf()函数。 #define _stscanf swscanf 用法如下: ULONGLONG l; CString str; _stscanf( (LPCTSTR)str, _T("%I64u"), &l); 当然,现在应该使用安全版本的swscanf_s()函数了。 【ULONGLONG转CString】 其实从数字转化到字符串属于“格式化”的情况,格式化函数常用于将非字符串类型的数据转换为CString。这个跟printf和scanf的情况类似,需要使用格式化符号。而CString的格式化函数就叫做Format()。用法如下: ULONGLONG l; CString str; str.Format( _T("%I64u") , l ); “I64”表示64位,“u”表示无符号,前面的“_T()”表示结果要转化为Unicode模式,如果你现在的工作环境并不是Unicode环境,那就没有必要转化了。 ===============================CString转char=============================== char型其实不仅仅是char型,实际上这里还指char*/const char*/char []等类型。这里请注意:写明char型实际上已经表示这是单字节型,肯定不是Unicode,所以只要你在Unicode环境中看到char类型,那转换肯定是必不可少的了。 PS:Windows中的LPCSTR类型与const char*是完全等价的,这不存在是否Unicode问题。因为其定义就是: typedef __nullterminated CONST CHAR *LPCSTR PS2:请注意区别LPCSTR和LPCTSTR这一对,区别LPSTR和LPTSTR这一对。也就是中间带T的就表示它们是基于TCHAR的,也就跟CString一样,能用于两种环境。而不带T的只能用于ANSI环境。搞清这一点,其实这些类型就不容易混了。 用个比喻的说法就是:带T的类型LPTSTR和LPCTSTR就是人妖,又可以当男的,又可以当女的。。。看环境不同吧。。。 【const char*转CString】 这个虽然看起来很难,但实际上很简单。 在非Unicode环境中,我们可以直接用: CString str = "hello world"; 来初始化CString。用构造函数形式也是没有问题的: CString str("hello world"); 但是在Unicode环境下,必须要转型: CString str( _T("hello world") ); 也就是说,CString的构造函数和_T()转型符替我们完成了从const char*向CString转型的过程,细节被隐藏了。 当然,你也可以用下面说到的两种方法的逆向方法。参见这里:http://hi.baidu.com/unix_dnybz/blog/item/21713354fd6511163b2935f0.html 注意哦:下面的代码在Unicode环境下面会出现乱码。 char* ch = "hello"; CString str; str.Format( "%s", ch );//小写s 【CString转const char*】 这个问题的实质在于CString是一个数组,而const char*是一个指针,是以null字符结尾的。这个网上似乎有不少办法,但是都离不开使用Windows API。 法1:USES_CONVERSION和W2A宏。W2A宏实际上就是“wide character to ansi”的意思。 CString str; USES_CONVERSION; const char* ch = W2A( str.LockBuffer() ); str.UnlockBuffer(); 法2:WideCharToMultiByte(),以及wctomb()函数--函数名也是wide char to multi byte的意思。 这个用法太麻烦了。但是它的功能更强大,可以用在中文内码转换上(不懂。。。),参见这里: http://www.vckbase.com/document/viewdoc/?id=1709 ===============================CString转宽字符=================================== 宽字符除了前面说过的在Unicode环境下的LPTSTR和LPCTSTR(人妖。。。)以外,还有专用的宽字符字符串LPWSTR,其定义为: typedef __nullterminated WCHAR *LPWSTR; 这就表示这是一个以NULL字符结尾的字符串指针。基于的类型是WCHAR,即wchar_t。 这其实就是相当于在C语言中一直就存在的char []和char*问题一样。MFC的CString类提供了这样一个函数将字符数组转化为以NULL字符结尾的字符串指针,用法如下: CString cstr = _T("hello world"); LPWSTR pszText = cstr.AllocSysString(); |