[MFC]CString与其他类型的转换

    技术2022-05-19  23

    在MFC中CString是字符串的常用表示方法,但是还有很多别的类型,例如数字类型等。(PS:微软的人真是不容易,折腾出这么多种类型来。。。)

     

    ==================================基础知识=====================================

     

    这一部分肯定是要首先知道什么叫“单字节字符”、“宽字符”和“多字节字符”。

    参见:http://www.dzsc.com/data/html/2008-9-12/69107.html

    所以“单字节字符”=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()。可以参见相应的百度百科词条(http://baike.baidu.com/view/1364018.htm)。其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();

     

     


    最新回复(0)