有关Unicode和非Unicode之间的转化问题

       自昨天开了博客之后,就打算今天晚上写点什么来作为我的第一篇博客(处女作)。

       经过百般考量,小编决定写写有关Unicode和非Unicode编码下,一些类型转化的问题。(其实是小编对这整整一个晚上的代码调试,对Unicode和非Unicode之间的转化的麻烦报以深深的控诉。难道统一一下会死啊)

       好,小编的白癜风发完了。我们进入正题。

       什么是Unicode?

       百度百科的定义:

Unicode统一码、万国码、单一码)是一种在计算机上使用的字符编码。Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。

       非Unicode则顾名思义。

 

       在vs2013中,编译器都会默认设置为“使用Unicode字符集”,也就是说我们使用的都是Unicode字符编码。然而Unicode环境下字符占两个字节,而在非Unicode环境下只占一个字节。正是因为如此,导致字符类型之间转化的困难。

       

       问题一:

             在vs2013 MFC开发中,默认基于Unicode环境下,获取编辑框中的字符,赋给string类型变量。

 CString name;
 m_name.GetWindowText(name);
 string tempName = name.GetBuffer();                         //通常情况下,CString转化为string类型可以调用GetBuffer()函数
       错误:

无法从“wchar_t *”转换为“std::basic_string<char,std::char_traits<char>,std::allocator<char>>” 

        这是小编面临的第一个问题。错误显示:无法从wchar_t 转化为 char , 或者是从wstring 转化为 string 。

        MFC的开发环境中,使用的控件都会有自己特定的类。比如CEdit,CListCtrl,这些类的成员方法(无论是形参还是返回值)大部分都是关于Unicode字符集的。也就是说使用string、char等作为这些方法的实参是都会出现编译错误。

        例如:

CListCtrl.InsertItem(0, str);

CListCtrl.SetItemText(0, 1, str);

        以上两个是CListCtrl的成员方法,其中str必须是基于Unicode的类型变量,例如CString、char*。

       当我们想到string 转化为 char*可以直接使用.c_str() 这个方法。然而在Unicode编码不同的情况下,就会出现const char*无法转化为char*的错误。

 

        解决方法:

               解决这类型的错误,主要原因是我们的变量转化的时候字节数一个是1,一个是2。我们要把字节数统一。

        Unicode转非Unicode:

               可以使用CT2A,如刚才的例子

 CString name;
 m_name.GetWindowText(name);
 string tempName = CT2A(name.GetBuffer());      可以解决。

               在一些方法里,会留有非Unicode的方法,例如:

TextOut(xdc,x,y,_T(text),strlen(text));             (非Unicode版)->                TextOutA(xdc,x,y,_T(text),strlen(text));

               最根本的,可以在项目的管理器里把“Unicode字符集”改为“多字符集”,但是在项目中途改动会出现错误。

               改动的路径为:项目 -> 属性 -> 配置属性 -> 常规 -> 字符集

 

        非Unicode转Unicode:
                使用_T("")宏和L都是比较简单的方法,但实用性不强。

                这里介绍最为安全和实用的函数MultiByteToWideChar函数,使用方法如下:

 nLen = (int)getname.length();
 name.resize(nLen, L' ');
 nResult = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)getname.c_str(), nLen, (LPWSTR)name.c_str(), nLen);
 CListCtrl.InsertItem(i, name.c_str());

                 这情况下,可以把一个非Unicode的string类型转化为Unicode的wstring类型。

                 与其相对应的wstring转string类型使用的函数是WideCharToMultiByte(),代码实例如下:

int nLen = (int)wstr.length();
str.resize(nLen, ' ');
int nResult = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)wstr.c_str(), nLen, (LPSTR)str.c_str(), nLen, NULL, NULL);

 

          以上两个方法是专属解决多字节和宽字节问题的。

          以上问题同时关系到LPCTSTR、LPCWSTR转化问题。

 

         最后附上几个转化的方法(正确性和使用性未知)

1、string 转 CString

       CString.format("%s", string.c_str());

2、char * 转 CString

      CString.format("%s", char*);

3、char * 转 string

    string s(char *);

4、string 转 char *

     char *p = string.c_str();

5、CString 转 string

      string s(CString.GetBuffer(CString.GetLength()));

6、CString 转 char *

charpoint=strtest.GetBuffer(strtest.GetLength());

      不建议用(LPCTSTR)进行强制类型转化,这样strtest大小发生变化时会出现错误。

7、CString 转 char[100]

      char a[100];

      CString str("aaaaaa");

       strncpy(a,(LPCTSTR)str,sizeof(a));

 

最后记录一个有关类型转化的博客:http://blog.csdn.net/sunuechao/article/details/7779351

 

最后感谢我找到的所有的博客、文章和百度。

 

最后的最后,现在是凌晨2点43分。

      

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值