Unicode 与 ANSI 字符串转换

时间:2023-01-10 15:40:57

如果你经常在 Windows 平台下写程序的话,我相信你一定会遇到 Unicode 与 ANSI 字符串之间的转换(string <-> CString之类的)。


要想实现 Unicode 和 ANSI 之间的转换,我之前的一篇文章中简单的介绍了一下:VS 系列 CString 转 string 方法,其实文中的方法是我蒙出来的,简单有效,至于原理我也不甚明了。大部分人使用的是以下两种函数来实现两者的转换:


1) ANSI -> Unicode

int MultiByteToWideChar(  __in  UINT CodePage,// 标识了与多字节关联的一个代码页值  __in  DWORD dwFlags,// 允许我们进行额外的控制,它会影响带变音符号(比如重音)的字符。但是一般情况下不适用,赋为 0 即可。  __in  LPCSTR lpMultiByteStr,// 参数指定要转换的字符串  __in  int cbMultiByte,      // 指定要转换串长度的长度(字节数),如果参数值是-1,函数便可自动判断源字符串的长度  __out LPWSTR lpWideCharStr, // 指定转换后Unicode版本的字符串内存地址  __in  int cchWideChar       // 指定 lpWideCharStr 缓冲区的最大长度。                                // 如果传入0,函数不会进行转换,而是返回一个宽字符数(包括终止字符'\0'),                // 只有当缓冲区能够容纳该数量的宽字符时,转换才会成功。);

转换步骤:

(1)调用 MultiByteToWideChar,为 pWideCharStr 参数传入 NULL, 为cchWideChar 参数传入 0,为 cbMultiByte 参数传入 -1 

(2)分配一块足以容纳转换后的 Unicode 字符串的内容。它的大小是上一个 MultiByteToWideChar 调用的返回值乘以 sizeof(wchar_t) 

(3)再次调用MultiByteToWideChar,这一次将缓冲区地址作为 pWideCharStr 参数的值传入,将第一次 MultiByteToWideChar 调用的返回值乘以 sizeof(wchar_t) 后得到大小作为 cchWideChar 参数的值传入。

(4)使用转换后的字符串

(5)释放 Unicode 字符串占用的内存块。

示例代码:

/* * Subject: Convert ANSI to Unicode * IDE: Visual Studio 2008 * Auther: http://www.cnblogs.com/chinazhangjie * Mail: chinajiezhang@gmail.com * Date:2011/10/10 */ #include
<stdio.h>
#include
<windows.h>
 int main(){    char *pANSI="ANSI to Unicode, ANSI 转换到 Unicode";    wchar_t *pUnicode = NULL;    int nWideCharLen = 0;     // step.1    nWideCharLen= MultiByteToWideChar(CP_ACP,0,pANSI,-1,NULL,0);    printf("nWideCharLen=%d\n", nWideCharLen);     // step.2    pUnicode = (wchar_t*)malloc(nWideCharLen * sizeof(wchar_t));     // step.3    MultiByteToWideChar(CP_ACP, 0, pANSI, -1, pUnicode, nWideCharLen * sizeof(wchar_t));     // step.4    MessageBoxW(NULL, pUnicode, TEXT("Unicode"), 0);     // step.5    free(pUnicode);     return 0;}

2) Unicode->ANSI

int WideCharToMultiByte(  __in  UINT CodePage,  // 标志了要与新转换的字符串关联的代码页  __in  DWORD dwFlags,  // 制定额外的转换控制,一般不需要进行这种程度的控制,而为 dwFlag 传入 0  __in  LPCWSTR lpWideCharStr,// 指定要转换的字符串的内存地址  __in  int cchWideChar,      // 指出该字符串的长度,如果传入 -1 ,则由函数来判断字符串的长度  __out LPSTR lpMultiByteStr, // 转换后的缓冲区  __in  int cbMultiByte,      // 指定 lpMultiByteStr 缓冲区的最大大小(字节数),如果传入 0 ,函数返回该目标缓冲区需要的大小  __in  LPCSTR lpDefaultChar,   __out LPBOOL lpUsedDefaultChar// 宽字符字符串中,如果至少有一个字符不能转换为对应的多字节形式,函数就会把这个变量设为 TRUE 。如果所有字符都能成功转换,就会把这个变量设为 FALSE。 通常将此函数传入 NULL 值。);


只有一个字符在 uCodePage 制定的代码页中没有对应的表示时,WideCharToMultiByte 才会使用后两个参数。在遇到一个不能转换的字符时,函数便使用 pDefaultChar 参数指向的字符。如果这个参数指向为 NULL ,函数就会使用一个默认的字符。这个默认的值通常是一个问号。这对文件操作是非常危险的,因为问号是一个通配符。


转换步骤和 ANSI -> Unicode 相似,故不做赘述。


示例代码:

/* * Subject: Convert Unicode to ANSI * IDE: Visual Studio 2008 * Auther: http://www.cnblogs.com/chinazhangjie * Mail: chinajiezhang@gmail.com * Date:2011/10/10 */ #include
<stdio.h>
#include
<windows.h>
 int main(){    wchar_t *pUnicode = TEXT("Convert Unicode to ANSI, Unicode 转换为 ANSI");    char    *pANSI    = NULL;    int      nByte     = 0;     // step.1    nByte = WideCharToMultiByte(CP_ACP, 0, pUnicode, -1, NULL, 0, NULL, NULL);     // step.2    pANSI = (char*)malloc(nByte);     // step.3    WideCharToMultiByte(CP_ACP, 0, pUnicode, -1, pANSI, nByte, NULL, NULL);     // step.4    printf_s("ANSI = %s\n", pANSI);     // step.5    free(pANSI);     return 0;}

转自<独酌逸醉>


Unicode下CString与char *转换 

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

(1)、Unicode下CString转换为char*

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

<span style="font-size:18px;">  CString str = _T("12345671234567");
//注意:以下n和len的值大小不同,n是按字符计算的,len = n + 1
int n = str.GetLength(); // n = 14, len = 15
//获取宽字节字符的大小,包括结束符
int len =WideCharToMultiByte(CP_ACP,0,str,-1,NULL,0,NULL,NULL);
//为多字节字符数组申请空间,数组大小为计算的宽字节字节大小
char * pFileName = new char[len]; //以字节为单位
//宽字节编码转换成多字节编码
WideCharToMultiByte(CP_ACP,0,str,-1,pFileName,len,NULL,NULL);</span>


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

 

<span style="font-size:18px;">//注意:有时候可能还需要添加引用#include   <afxpriv.h>
CString str = L"12345";
//声明标识符
USES_CONVERSION;
//调用函数,T2A和W2A均支持ATL和MFC中的字符转换
char * pFileName = T2A(str);
//char * pFileName = W2A(str);//也可实现转换</span>

(2)、Unicode下char*转换为CString

 

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

<span style="font-size:18px;">char * pFileName = "12345678";

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

//计算多字节字符的大小,按字符计算。
int wcharlen = MultiByteToWideChar(CP_ACP,0,pFileName,-1,NULL,0);//9

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

//多字节编码转换成宽字节编码
MultiByteToWideChar(CP_ACP,0,pFileName,-1, buf, wcharlen);

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

//删除缓冲区
delete []buf;</span>

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

<span style="font-size:18px;">char * pFileName = "12345678";

USES_CONVERSION;
CString s = A2T(pFileName);

//CString s = A2W(pFileName);</span>
 

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

<span style="font-size:18px;">//书写代码使用TEXT("")或_T(""),文本在UNICODE和非UNICODE程序里都通用
AfxMessageBox(_T("加载数据失败"),0);

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

方法四:使用Format函数

<span style="font-size:18px;"><strong>        </strong>CString str;
char p[]="123123";
TCHAR s[] = L"123123";
str.Format(L"%S--%s", p , s);//在Unicode字符集下,%S 的参数看做ANSII字符串 %s为Unicode字符串</span>

Unicode

CString转TCHAR 

<span style="font-size:18px;">CString str = L"12345";
//str.GetLength() = wcslen(str);
TCHAR* szMsg = new TCHAR[wcslen(str)+1];
szMsg = str.GetBuffer(str.GetLength());
str.ReleaseBuffer();
//用完了别忘了
delete []szMsg;</span>
</pre><p style="line-height: 21.6px;"></p><p align="left" style="color: rgb(51, 51, 51); line-height: 26px;"><span style="font-size:18px;"><span style="color: black;">CString</span><span style="color: black;">转 int</span></span></p><p align="left" style="color: rgb(51, 51, 51); line-height: 26px;"></p><pre name="code" class="cpp" style="line-height: 21.6px;"><span style="font-size:18px;">CString strNum=_T(“”);int value =_ttoi(static_cast<LPCTSTR>(strNum));//或者int value = _ttoi(strNum);</span>
     

int 转CString

<span style="font-size:18px;">int ia=1232;
CString stri=stri.Format(_T(“%d”),ia);</span>