UniCode 下 CString 与 char*互转 的方法

今天进行文件操作时,将CString的GetBuffer()后直接倒到char数组后写入文件发现 每个字符与字符之间都有一个空格存在,而且有内容丢失。原来CString类对象GetBuffer(),后以后还是unicode编码,所以必须将宽字符转换成char类型那就必须用到一个函数

 

网上查了下解决方法如下:

 

在Visual C++.NET2005中,默认的字符集形式是Unicode,但在VC6.0等工程中,默认的字符集形式是多字节字符集(MBCS:Multi-Byte Character Set),这样导致在VC6.0中非常简单实用的各类字符操作和函数在VS2005环境下运行时会报各种各样的错误,这里总结了在Visual C++.NET2005环境中Unicode字符集下CString和char *之间相互转换的几种方法,其实也就是Unicode字符集与MBCS字符集转换。

 

WideCharToMultiByte
函数功能:该函数映射一个unicode字符串到一个多 字节字符串。
函数原型:
int WideCharToMultiByte(
UINT  CodePage, //指定执行转换的 代码页
DWORD  dwFlags,
LPCWSTR  lpWideCharStr, //指定的宽 字节字符串的 缓冲区
int  cchWideChar, //指定由参数lpWideCharStr指向的 缓冲区字符个数
LPSTR  lpMultiByteStr, //指向接收被转换字符串的缓冲区
int  cchMultiByte, //指定由参数lpMultiByteStr指向的 缓冲区最大值
LPCSTR  lpDefaultChar,
LPBOOL  pfUsedDefaultChar
);
参数:
CodePage:指定执行转换的 代码页,这个参数可以为系统已安装或有效的任何代码页所给定的值。你也可以指定其为下面的任意一值:
CP_ACP:ANSI 代码页;CP_MACCP:Macintosh代码页;CP_OEMCP:OEM代码页;
CP_SYMBOL:符号 代码页(42);CP_THREAD_ACP:当前线程ANSI代码页;
CP_UTF7:使用UTF-7转换;CP_UTF8:使用UTF-8转换。
lpWideCharStr:指向将被转换的unicode字符串。
cchWideChar:指定由参数lpWideCharStr指向的 缓冲区的字符个数。如果这个值为-1,字符串将被设定为以NULL为结束符的字符串,并且自动计算长度。
lpMultiByteStr:指向接收被转换字符串的缓冲区。
cchMultiByte:指定由参数lpMultiByteStr指向的 缓冲区最大值(用 字节来计量)。若此值为零,函数返回lpMultiByteStr指向的目标 缓冲区所必需的字节数,在这种情况下,lpMultiByteStr参数通常为NULL。
lpDefaultCharpfUsedDefaultChar:只有当WideCharToMultiByte函数遇到一个宽 字节 字符,而该字符在uCodePage参数标识的 代码页中并没有它的表示法时,WideCharToMultiByte函数才使用这两个参数。如果宽 字节 字符不能被转换,该函数便使用lpDefaultChar参数指向的字符。如果该参数是NULL(这是大多数情况下的参数值),那么该函数使用系统的默认 字符。该默认 字符通常是个问号。这对于文件名来说是危险的,因为问号是个 通配符。pfUsedDefaultChar参数指向一个 布尔变量,如果Unicode 字符串中至少有一个字符不能转换成等价多 字节字符,那么函数就将该变量置为TRUE。如果所有 字符均被成功地转换,那么该函数就将该变量置为FALSE。当函数返回以便检查宽 字节字符串是否被成功地转换后,可以测试该变量。
返回值:如果函数运行成功,并且cchMultiByte不为零,返回值是由 lpMultiByteStr指向的 缓冲区中写入的字节数;如果函数运行成功,并且cchMultiByte为零,返回值是接收到待转换字符串的缓冲区所必需的字节数。如果函数运行失败,返回值为零。若想获得更多 错误信息,请调用GetLastError函数。它可以返回下面所列错误代码:
ERROR_INSUFFICIENT_BJFFER;ERROR_INVALID_FLAGS;
ERROR_INVALID_PARAMETER;ERROR_NO_UNICODE_TRANSLATION。
注意: 指针lpMultiByteStr和lpWideCharStr必须不一样。如果一样,函数将失败,GetLastError将返回ERROR_INVALID_PARAMETER的值。 
Windows CE:不支持参数CodePage中的CP_UTF7和CP_UTF8的值,以及参数dwFlags中的WC_NO_BEST_FIT_CHARS值。

1、Unicode下CString转换为char *

方法一:使用API:WideCharToMultiByte进行转换

              CString str = _T("D://校内项目//QQ.bmp");

            //注意:以下n和len的值大小不同,n是按字符计算的,len是按字节计算的
              int n = str.GetLength();     // n = 14, len = 18

             //获取宽字节字符的大小,大小是按字节计算的
             int len = WideCharToMultiByte(CP_ACP,0,str,str.GetLength(),NULL,0,NULL,NULL);

             //为多字节字符数组申请空间,数组大小为按字节计算的宽字节字节大小
            char * pFileName = new char[len+1];   //以字节为单位

            //宽字节编码转换成多字节编码
            WideCharToMultiByte(CP_ACP,0,str,str.GetLength(),pFileName,len,NULL,NULL);

             pFileName[len+1] = '/0';   //多字节字符以'/0'结束

方法二:使用函数:T2A、W2A

             CString str = _T("D://校内项目//QQ.bmp");

              //声明标识符
             USES_CONVERSION;

             //调用函数,T2A和W2A均支持ATL和MFC中的字符转换
             char * pFileName = T2A(str);   
             //char * pFileName = W2A(str); //也可实现转换

            注意:有时候可能还需要添加引用#include   <afxpriv.h>

2、Unicode下char *转换为CString

方法一:使用API:MultiByteToWideChar进行转换

               char * pFileName = "D://校内项目//QQ.bmp";

              //计算char *数组大小,以字节为单位,一个汉字占两个字节
             int charLen = strlen(pFileName);

             //计算多字节字符的大小,按字符计算。
             int len = MultiByteToWideChar(CP_ACP,0,pFileName,charLen,NULL,0);

              //为宽字节字符数组申请空间,数组大小为按字节计算的多字节字符大小
             TCHAR *buf = new TCHAR[len + 1];

               //多字节编码转换成宽字节编码
              MultiByteToWideChar(CP_ACP,0,pFileName,charLen,buf,len);

             buf[len] = '/0'; //添加字符串结尾,注意不是len+1

              //将TCHAR数组转换为CString
              CString pWideChar;
              pWideChar.Append(buf);

              //删除缓冲区
             delete []buf;

方法二:使用函数:A2T、A2W

               char * pFileName = "D://校内项目//QQ.bmp";

              USES_CONVERSION;
              CString s = A2T(pFileName);

             //CString s = A2W(pFileName);

方法三:使用_T宏,将字符串转换为宽字符

            //多字节字符集,在vc6和vc7种可以编译通过的语句,但VS2005不能通过,默认为Unicode字符集
            //AfxMessageBox("加载数据失败",0);

             //书写代码使用TEXT("")或_T(""),文本在UNICODE和非UNICODE程序里都通用
            AfxMessageBox(_T("加载数据失败"),0);  

       注意:直接转换在基于MBCS的工程可以,但在基于Unicode字符集的工程中直接转换是不可行的,CString会以Unicode的形式来保存数据,强制类型转换只会返回第一个字符。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值