VC++中ANSIUNICODE与UTF-8字符编码之间的转换(附源码)

Posted dvlinker

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了VC++中ANSIUNICODE与UTF-8字符编码之间的转换(附源码)相关的知识,希望对你有一定的参考价值。

       在C++软件开发过程中会时常遇到一些字符编码之间转换的问题,今天我们就来简单的说明一下。

       ANSI是窄字节字符编码,一般是存放在char型变量中,常见的GB2312就是中文字符的窄字节编码。UNICODE是宽字节字符编码,在该编码中所有的字符都占用两个字节,一个中文字符占连两个字节,一个英文或数字也是占两个字节。UTF-8是可变长字符编码,一个英文或数字只占一个字节,一个中文则占用3个字节。

       一般我们在开发Windows UI程序时,为了支持多国语言,UI界面使用的字符必须是UNICODE编码的。服务器程序则需要支持UTF-8字符编码,这样客户端与服务器交互时就会涉及到字符编码之间的转换。

1、ANSI与UNICODE之间的转换

        ANSI转成UNICODE:

/*=============================================================================
函 数 名: AnsiToUnicode
功    能: 实现将char型buffer(ANSI编码)中的内容安全地拷贝到指定的WChar型(Unicode编码)的buffer中
参    数: char*  pchSrc [in]          源字符串
          WCAHR* pchDest [out]        目标buf    
		  int nDestLen [in]           目标buf长度(注意:以字节为单位,不是以字符个数为单位)
注    意: 无
返 回 值: 无
=============================================================================*/
void AnsiToUnicode( const char* pchSrc, WCHAR* pchDest, int nDestLen )

	if ( pchSrc == NULL || pchDest == NULL )
	
		return;
	
 
	int nTmpLen = MultiByteToWideChar(CP_ACP, 0, pchSrc, -1, NULL, 0);
	WCHAR* pWTemp = new WCHAR[nTmpLen + 1];
	memset(pWTemp, 0, (nTmpLen + 1) * sizeof(WCHAR));
	MultiByteToWideChar(CP_ACP, 0, pchSrc, -1, pWTemp, nTmpLen + 1);
 
	UINT nLen = wcslen(pWTemp);
	if (nLen + 1 > (nDestLen / sizeof(WCHAR)))
	
		wcsncpy(pchDest, pWTemp, nDestLen / sizeof(WCHAR) - 1);
		pchDest[nDestLen / sizeof(WCHAR) - 1] = 0;
	
	else
	
		wcscpy(pchDest, pWTemp);
	
 
	delete []pWTemp;

        UNICODE转成ANSI:

/*=============================================================================
函 数 名: Utf8ToUnicode
功    能: 实现将char型的buffer(utf8编码)中的内容安全地拷贝到指定的WCHAR型buffer(Unicode编码)中
参    数: char* pchSrc [in]          源字符串
          WCHAR* pchDest [out]     目标buf		 
		  int nDestLen [in]           目标buf长度(注意:以字节为单位,不是以字符个数为单位)
注    意: 无
返 回 值: 无
=============================================================================*/
void Utf8ToUnicode( const char* pchSrc, WCHAR* pchDest, int nDestLen )

	if ( pchSrc == NULL || pchDest == NULL )
	
		return;
	
 
	int nTmpLen = MultiByteToWideChar(CP_UTF8, 0, pchSrc, -1, NULL, 0);
	WCHAR* pWTemp = new WCHAR[nTmpLen + 1];
	memset(pWTemp, 0, (nTmpLen + 1) * sizeof(WCHAR));
	MultiByteToWideChar(CP_UTF8, 0, pchSrc, -1, pWTemp, nTmpLen + 1);
 
	UINT nLen = wcslen(pWTemp);
	if (nLen + 1 > (nDestLen / sizeof(WCHAR)))
	
		wcsncpy(pchDest, pWTemp, nDestLen / sizeof(WCHAR) - 1);
		pchDest[nDestLen / sizeof(WCHAR) - 1] = 0;
	
	else
	
		wcscpy(pchDest, pWTemp);
	
 
	delete []pWTemp;

 2、UTF-8与UNICODE之间的转换

       UTF-8转成UNICODE:

/*=============================================================================
函 数 名: Utf8ToUnicode
功    能: 实现将char型的buffer(utf8编码)中的内容安全地拷贝到指定的WCHAR型buffer(Unicode编码)中
参    数: char* pchSrc [in]          源字符串
          WCHAR* pchDest [out]     目标buf		 
		  int nDestLen [in]           目标buf长度(注意:以字节为单位,不是以字符个数为单位)
注    意: 无
返 回 值: 无
=============================================================================*/
void Utf8ToUnicode( const char* pchSrc, WCHAR* pchDest, int nDestLen )

	if ( pchSrc == NULL || pchDest == NULL )
	
		return;
	
 
	int nTmpLen = MultiByteToWideChar(CP_UTF8, 0, pchSrc, -1, NULL, 0);
	WCHAR* pWTemp = new WCHAR[nTmpLen + 1];
	memset(pWTemp, 0, (nTmpLen + 1) * sizeof(WCHAR));
	MultiByteToWideChar(CP_UTF8, 0, pchSrc, -1, pWTemp, nTmpLen + 1);
 
	UINT nLen = wcslen(pWTemp);
	if (nLen + 1 > (nDestLen / sizeof(WCHAR)))
	
		wcsncpy(pchDest, pWTemp, nDestLen / sizeof(WCHAR) - 1);
		pchDest[nDestLen / sizeof(WCHAR) - 1] = 0;
	
	else
	
		wcscpy(pchDest, pWTemp);
	
 
	delete []pWTemp;

       UNICODE转成 UTF-8:

/*=============================================================================
函 数 名: UnicodeToUtf8
功    能: 实现将WCHAR型buffer(Unicode编码)中的内容安全地拷贝到指定的char型的buffer(utf8编码)中
参    数: WCAHR* pchSrc [in]          源字符串
          char* pchDest [out]     目标buf	  
		  int nDestLen [in]           目标buf长度(注意:以字节为单位,不是以字符个数为单位)
注    意: 无
返 回 值: 无
=============================================================================*/
void UnicodeToUtf8(const WCHAR* pchSrc, char* pchDest, int nDestLen );

	if ( pchDest == NULL || pchSrc == NULL )
	
		return;
	
 
	const WCHAR* pWStrSRc = pchSrc;
	int nTmplen = WideCharToMultiByte(CP_UTF8, 0, pWStrSRc, -1, NULL, 0, NULL, NULL);
	char* pTemp = new char[nTmplen + 1];
	memset(pTemp, 0, nTmplen + 1);
	WideCharToMultiByte(CP_UTF8, 0, pWStrSRc, -1, pTemp, nTmplen + 1, NULL, NULL);
 
	int nLen = strlen(pTemp);
	if (nLen + 1 > nDestLen)
	
		strncpy(pchDest, pTemp, nDestLen - 1);
		pchDest[nDestLen - 1] = 0;
	
	else
	
		strcpy(pchDest, pTemp);
	
 
	delete []pTemp;

 3、ANSI与UTF-8之间的转换

       ANSI与UTF8之间是不能直接转换的,需要先转成Unicode之后才能转到目标编码。

       ANSI转成UTF8的代码如下:

/*=============================================================================
函 数 名: AnsiToUtf8
功    能: 实现将char型buffer(ANSI编码)中的内容安全地拷贝到指定的char型的buffer(utf8编码)中
参    数: char* pchSrc [in]          源字符串
          char* pchDest [out]     目标buf
		  int nDestLen [in]           目标buf长度(注意:以字节为单位,不是以字符个数为单位)
注    意: 无
返 回 值: 无
=============================================================================*/
void AnsiToUtf8( const char* pchSrc, char* pchDest, int nDestLen ) 

	if (pchSrc == NULL || pchDest == NULL)
	
		return;
	
 
	// 先将ANSI转成Unicode
	int nUnicodeBufLen = MultiByteToWideChar(CP_ACP, 0, pchSrc, -1, NULL, 0);
	WCHAR* pUnicodeTmpBuf = new WCHAR[nUnicodeBufLen + 1];
	memset(pUnicodeTmpBuf, 0, (nUnicodeBufLen + 1) * sizeof(WCHAR));
	MultiByteToWideChar(CP_ACP, 0, pchSrc, -1, pUnicodeTmpBuf, nUnicodeBufLen + 1);
 
	// 再将Unicode转成utf8
	int nUtf8BufLen = WideCharToMultiByte(CP_UTF8, 0, pUnicodeTmpBuf, -1, NULL, 0, NULL, NULL);
	char* pUtf8TmpBuf = new char[nUtf8BufLen + 1];
	memset(pUtf8TmpBuf, 0, nUtf8BufLen + 1);
	WideCharToMultiByte(CP_UTF8, 0, pUnicodeTmpBuf, -1, pUtf8TmpBuf, nUtf8BufLen + 1, NULL, NULL);
 
	int nLen = strlen(pUtf8TmpBuf);
	if (nLen + 1 > nDestLen)
	
		strncpy(pchDest, pUtf8TmpBuf, nDestLen - 1);
		pchDest[nDestLen - 1] = 0;
	
	else
	
		strcpy(pchDest, pUtf8TmpBuf);
	
 
	delete[]pUtf8TmpBuf;
	delete[]pUnicodeTmpBuf;

       UTF8转成ANSI的代码如下:

/*=============================================================================
函 数 名: Utf8ToAnsi
功    能: 实现将char型buffer(utf8编码)中的内容安全地拷贝到指定的char型的buffer(ANSI编码)中
参    数: char* pchSrc [in]          源字符串
		  char* pchDest [out]     目标buf
		  int nDestLen [in]           目标buf长度(注意:以字节为单位,不是以字符个数为单位)
注    意: 无
返 回 值: 无
=============================================================================*/
void Utf8ToAnsi(const char* pchSrc, char* pchDest, int nDestLen)

	if (pchSrc == NULL || pchDest == NULL)
	
		return;
	
 
	// 先将utf8转成Unicode
	int nUnicdeBufLen = MultiByteToWideChar(CP_UTF8, 0, pchSrc, -1, NULL, 0);
	WCHAR* pUnicodeTmpBuf = new WCHAR[nUnicdeBufLen + 1];
	memset(pUnicodeTmpBuf, 0, (nUnicdeBufLen + 1) * sizeof(WCHAR));
	MultiByteToWideChar(CP_UTF8, 0, pchSrc, -1, pUnicodeTmpBuf, nUnicdeBufLen + 1);
 
	// 再将Unicode转成utf8
	int nAnsiBuflen = WideCharToMultiByte(CP_ACP, 0, pUnicodeTmpBuf, -1, NULL, 0, NULL, NULL);
	char* pAnsiTmpBuf = new char[nAnsiBuflen + 1];
	memset(pAnsiTmpBuf, 0, nAnsiBuflen + 1);
	WideCharToMultiByte(CP_ACP, 0, pUnicodeTmpBuf, -1, pAnsiTmpBuf, nAnsiBuflen + 1, NULL, NULL);
 
	int nLen = strlen(pAnsiTmpBuf);
	if (nLen + 1 > nDestLen)
	
		strncpy(pchDest, pAnsiTmpBuf, nDestLen - 1);
		pchDest[nDestLen - 1] = 0;
	
	else
	
		strcpy(pchDest, pTemp);
	
 
	delete []pAnsiTmpBuf;
	delete []pUnicodeTmpBuf;

        以上就是上述字符编码之间相互转换的代码,希望能给大家提供一定的帮助!

        关于字符编码的详细介绍,可以参见我另外一篇博客:

一文带你弄懂C++中的ANSI、Unicode和UTF8三种字符编码https://blog.csdn.net/chenlycly/article/details/121070073

以上是关于VC++中ANSIUNICODE与UTF-8字符编码之间的转换(附源码)的主要内容,如果未能解决你的问题,请参考以下文章

让VC调试器正确显示UTF-8字符串

Servlet 知识点 中文乱码的本质与解决

Java 使用URLEncoder.encode和URLDecoder.decode编解码(utf-8)中文及特殊字符

字符编码中ASCIIUnicode和UTF-8的区别

字符编码及文件操作

ASCII, Unicode 与 UTF-8