WideCharToMultiByte和MultiByteToWideChar函式的用法(ascii轉unicode unicode轉ascii)

whatday發表於2013-06-07
為了支援Unicode編碼,需要多位元組與寬位元組之間的相互轉換。這兩個系統函式在使用時需要指定內碼表,在實際應用過程中遇到亂碼問題,然後重新閱讀《Windows核心程式設計》,總結出正確的用法。
WideCharToMultiByte的內碼表用來標記與新轉換的字串相關的內碼表。
MultiByteToWideChar的內碼表用來標記與一個多位元組字串相關的內碼表。
常用的內碼表由CP_ACP和CP_UTF8兩個。
使用CP_ACP內碼表就實現了ANSI與Unicode之間的轉換。
使用CP_UTF8內碼表就實現了UTF-8與Unicode之間的轉換。
下面是程式碼實現:
1.  ANSI to Unicode
wstring ANSIToUnicode( const string& str )
{
 int  len = 0;
 len = str.length();
 int  unicodeLen = ::MultiByteToWideChar( CP_ACP,
            0,
            str.c_str(),
            -1,
            NULL,
            0 ); 
 wchar_t *  pUnicode; 
 pUnicode = new  wchar_t[unicodeLen+1]; 
 memset(pUnicode,0,(unicodeLen+1)*sizeof(wchar_t)); 
 ::MultiByteToWideChar( CP_ACP,
         0,
         str.c_str(),
         -1,
         (LPWSTR)pUnicode,
         unicodeLen ); 
 wstring  rt; 
 rt = ( wchar_t* )pUnicode;
 delete  pUnicode;
 
 return  rt; 
}
2.  Unicode to ANSI
string UnicodeToANSI( const wstring& str )
{
 char*     pElementText;
 int    iTextLen;
 // wide char to multi char
 iTextLen = WideCharToMultiByte( CP_ACP,
         0,
         str.c_str(),
         -1,
         NULL,
         0,
NULL,
         NULL );
 pElementText = new char[iTextLen + 1];
 memset( ( void* )pElementText, 0, sizeof( char ) * ( iTextLen + 1 ) );
 ::WideCharToMultiByte( CP_ACP,
         0,
         str.c_str(),
         -1,
         pElementText,
         iTextLen,
         NULL,
         NULL );
 string strText;
 strText = pElementText;
 delete[] pElementText;
 return strText;
}
3.  UTF-8 to Unicode
wstring UTF8ToUnicode( const string& str )
{
 int  len = 0;
 len = str.length();
 int  unicodeLen = ::MultiByteToWideChar( CP_UTF8,
            0,
            str.c_str(),
            -1,
            NULL,
            0 ); 
 wchar_t *  pUnicode; 
 pUnicode = new  wchar_t[unicodeLen+1]; 
 memset(pUnicode,0,(unicodeLen+1)*sizeof(wchar_t)); 
 ::MultiByteToWideChar( CP_UTF8,
         0,
         str.c_str(),
         -1,
         (LPWSTR)pUnicode,
         unicodeLen ); 
 wstring  rt; 
 rt = ( wchar_t* )pUnicode;
 delete  pUnicode;
 
 return  rt; 
}
4.  Unicode to UTF-8   
string UnicodeToUTF8( const wstring& str )
{
 char*     pElementText;
 int    iTextLen;
 // wide char to multi char
 iTextLen = WideCharToMultiByte( CP_UTF8,
         0,
         str.c_str(),
         -1,
         NULL,
         0,
         NULL,
         NULL );
 pElementText = new char[iTextLen + 1];
 memset( ( void* )pElementText, 0, sizeof( char ) * ( iTextLen + 1 ) );
 ::WideCharToMultiByte( CP_UTF8,
         0,
         str.c_str(),
         -1,
         pElementText,
         iTextLen,
         NULL,
         NULL );
 string strText;
 strText = pElementText;
 delete[] pElementText;
 return strText;

}


====================================================================

轉換程式碼:

//Uniocde 和 ASCII 的轉換 bFlg==TRUE:UNICODE->ASCII  FLASE:ASCII->UNICODE  
//bIsAlloc為自動申請記憶體/手動申請記憶體 如果是自動模式需要呼叫者自己釋放 如HeapFree(GetProcessHeap(), 0, pcName); 手動模式則是建立者自己釋放
void Unicode2Ascii(PWCHAR *pwStr, PCHAR *pcStr, BOOL bFlg, BOOL bIsAlloc=TRUE)
{
	int nSizeW, nSizeC;

	//UNICODE 轉 ASCII
	if(bFlg)
	{
		nSizeW=wcslen(*pwStr);
		nSizeC=WideCharToMultiByte(CP_ACP, 0, *pwStr, nSizeW, NULL, 0, NULL, NULL);
		//自動申請記憶體
		if(bIsAlloc)
		{
			*pcStr = (CHAR*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (nSizeC + 1) * sizeof(CHAR));
		}
		//手動申請記憶體
		else
		{
			memset(*pcStr, 0, (nSizeC + 1) * sizeof(CHAR));
		}
		
		WideCharToMultiByte(CP_ACP, 0, *pwStr, nSizeW, *pcStr, nSizeC * sizeof(CHAR), NULL, NULL);
	}
	//ASCII 轉 UNICODE
	else
	{
		nSizeC=MultiByteToWideChar(CP_ACP, 0, *pcStr, -1, NULL, 0);
		if(bIsAlloc)
		{
			*pwStr= (PWCHAR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (nSizeC+1) * sizeof(WCHAR));
		}
		else
		{
			memset(*pwStr, 0, (nSizeC+1) * sizeof(WCHAR));
		}
		
		MultiByteToWideChar(CP_ACP, 0, *pcStr, -1, *pwStr, nSizeC * sizeof(WCHAR));
	}
}


相關文章