在C++软件开发过程中会时常遇到一些字符编码之间转换的问题,今天我们就来简单的说明一下。
ANSI是窄字节字符编码,一般是存放在char型变量中,常见的GB2312就是中文字符的窄字节编码。UNICODE是宽字节字符编码,在该编码中所有的字符都占用两个字节,一个中文字符占连两个字节,一个英文或数字也是占两个字节。UTF-8是可变长字符编码,一个英文或数字只占一个字节,一个中文则占用3个字节。
一般我们在开发Windows UI程序时,为了支持多国语言,UI界面使用的字符必须是UNICODE编码的。服务器程序则需要支持UTF-8字符编码,这样客户端与服务器交互时就会涉及到字符编码之间的转换。
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;
}
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;
}
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