【C++】MFC中的CString和std::string,以及两者之间的相互转换(基于VS201X版本)

最近学了两天MFC,发现还比较有意思,准备过一段时间买一本《深入浅出MFC》,去好好学一下图形界面的框架以及其内部对系统调用的使用。
在使用MFC的时候,虽然界面和其表面逻辑框架都是使用MFC的,但其实大部分的内部逻辑我还是使用C++原生库去写的,比如今天花了两个小时写了两个MFC小程序——输入型多项式计算器(中缀转后缀,支持加减乘除括号的混合运算)、一个简单的汉英词典软件(解决一下自己平常打代码的时候的命名问题),其内部逻辑都是用C++内部自带的库(STL等)和命名空间std去实现的。
由于上面的两个小Demo都用到了比较多的字符串处理,而内部逻辑使用的是std::string,而在MFC这边,我取得的Edit_Control 中的数据是CString类型的,所以就要经过一些简单的转换。
所以,下面对CString和C++自带字符串类型(std::string)之间,进行转换的方法做一个小总结吧。

经过这几天的搜索学习,我发现网上介绍CString的东西特别少,所以我先介绍一下CString

CString

CStringT,实际上它是一个操作可变长度字符串的模板类。CStringT模板类有三个实例:CString、CStringACStringW,它们分别提供对TCHARcharwchar_t字符类型的字符串的操作。char类型定义的是Ansi字符,wchar_t类型定义的是Unicode字符,而TCHAR取决于MFC工程的属性对话框中的Configuration Properties->General->Character Set属性,如果此属性为Use Multi-Byte Character Set,则TCHAR类型定义的是Ansi字符,而如果为Use Unicode Character Set,则TCHAR类型定义的是Unicode字符。

几个常用函数:

  CString& MakeLower();

将字符串中的所有大写字符转换为小写字符。

     CString& MakeUpper();

将字符串中的所有小写字符转换为大写字符。

     CString& MakeReverse();

将字符串中所有字符的顺序颠倒。


CString对象的连接

多个CString对象的连接可以通过重载运算符+、+=实现。例如:

CString str(_T("google"));      // str内容为"google"   
str = _T("www.") + str + _T("."); // str为"www.google."   
str += _T("com");                 // str为"www.google.com"  

CString对象字符串的提取操作

CString Left(int nCount) const;

提取该字符串左边nCount个字符的子字符串,并返回一个包含这个子字符串的拷贝的CString对象。

CString Right(int nCount) const;

提取该字符串右边nCount个字符的子字符串,并返回一个包含这个子字符串的拷贝的CString对象。

CString Mid(int iFirst,int nCount) const;

提取该字符串中以索引iFirst位置开始的nCount个字符组成的子字符串,并返回一个包含这个子字符串的拷贝的CString对象。

CString Mid(int iFirst) const;

提取该字符串中以索引iFirst位置开始直至字符串结尾的子字符串,并返回一个包含这个子字符串的拷贝的CString对象。
如下:

CString str1 = _T("google");   
CString str2 = str1.Left(3);    // str2为"goo"   
str2 = str1.Right(2);           // str2为"le"   
str2 = str1.Mid(1,3);           // str2为"oog"   
str2 = str1.Mid(5);             // str2为"le"  

CString类的格式化字符串方法

使用CString类的Format成员函数可以将int、short、long、float、double等数据类型格式化为字符串对象。

 void __cdecl Format(PCXSTR pszFormat,[, argument]...);

参数pszFormat为格式控制字符串;参数argument可选,为要格式化的数据,一般每个argumentpszFormat中都有对应的表示其类型的子字符串,int型的argument对应的应该是"%d"float型的应对应"%f",等等。
例如:

CString str;   
int a = 1;   
float b = 2.3f;   
str.Format(_T("a=%d,b=%f"), a, b);  // str为"a=1,b=2.300000"  

CStringstd::string的相互转换

CString -> string

这里我使用了一下网上查到的方法,发现并不能用,其实想一想也对,string内置存储的是一个字节长的char类型字符,而CString存储的是两字节长的wchar_t类型。不能相互转换也比较正常,虽然可以直接强行转换。但也太过于粗暴了。

但是有一点我觉得比较奇怪,因为在我印象中string虽然内部是char类型的元素,但是在初始化的时候,会自动将那个汉字元素扩充成两个字符位置进行存储。
比如如下代码:


int main() 
{
    string str = "hi,你好";
    return 0;
}

调用调试,我们可以很容易的发现string内部的存储形式为如下方式:

这里写图片描述

可以发现,string内部还是使用的char类型进行汉字的存储,不过却是使用的两个char来存储。
不过如果我们如果单独用wchar_t 字符串对string进行初始化,就会出错。
所以我们在使用CStringstring挨个元素进行初始化的时候,发现string内部的元素却是使用的一个char进行存储wchar_t,这就导致了无法用CStringstring进行初始化的问题。

这样的字符转码真的导致了很大的问题,而且不好解决。解决方式有以下几种:

  • 我们可以使用wstring来进行字符串的存储和输出,然后用一对一的下标赋值的方式进行解决
  • 也可以直接用vs2015左右版本支持的方式CT2A(之前版本的也应该有相应的转换宏定义,不过是不是这个就不一定了,可以去查一下官方手册):
string c_str("你好");
string str = CT2A(mfc_str);
  • GetBuffer(0) 然后加一点转换,记得ReleaseBuffer()
CString mfc_str("Nihao1");
string str(CT2CA(mfc_str.GetBuffer(0)));

还是自己学的不好啊,看来这些基础还要再次重温一下。


string ->CString

相对于上面的转换,下面的转换就很简单了,直接用如下代码就OK:

string p("你好");
CString Cstr(p.c_str());

真的是…..很奇特。

就这样吧,等有空了再仔细看看字符的不同编码方式之间的转换吧。

  • 6
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值