解决你的乱码难题(Qt转码与char和utf8的互转)
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Shado_walker/article/details/56315359
在跨平台的开发中,字符串的转码显得相当重要,稍有不慎,将会出现乱码的情况,在这里,首先说一下Qt的QString中几个关于转码的函数:
(1)QByteArray toUtf8() const;
(2)std::string toStdString() const;
(3)QByteArray toLocal8Bit() const;
(4)QString fromUtf8(const QByteArray &str);
(5)QString fromStdString(const std::string &str);
(6)QString fromLocal8Bit(const QByteArray &str);
以上函数用好了,基本可以解决乱码的问题了,一般,如果是本地自己写的中文字符串,可以用QString fromLocal8Bit(const QByteArray &str);转换成QString,然后就可以正常显示了,如果是从其他地方获取的,根据情况进行转换,然后本地用QString fromLocal8Bit(const QByteArray &str);也可以正常显示。至于以上函数中的(1)(2)(3),都是将本地的字符串转换成指定编码的函数,可以查阅Qt的帮助了解详细用法。
下面的代码主要解决不用Qt的情况下,如何将char型的字符串转换成UTF8,以及如何将UTF8转换成char类型:
-
int char2utf8(const char *szIn, char *szOut){
-
int nResult = -1;
-
#ifdef _WIN32
-
int nLen = 0;
-
int nUnicodeLen = 0;
-
wchar_t *pUnicode = NULL;
-
BYTE *pTragetData = NULL;
-
int nTragetLen = 0;
-
//校验参数有效性
-
if (NULL == szIn)
-
{
-
//参数错误
-
goto _exit_;
-
}
-
//转换为unicode
-
nLen = lstrlenA(szIn);
-
nUnicodeLen = ::MultiByteToWideChar(CP_ACP, 0, szIn, -1, NULL, 0);
-
if (nUnicodeLen == 0)
-
{
-
//获取unicode缓存长度失败
-
goto _exit_;
-
}
-
pUnicode = new wchar_t[nUnicodeLen + 1];
-
ZeroMemory(pUnicode, (nUnicodeLen + 1)*sizeof(wchar_t));
-
nResult = ::MultiByteToWideChar(CP_ACP, 0, szIn, -1, (LPWSTR)pUnicode, nUnicodeLen);
-
if (0 == nResult)
-
{
-
//将源字符串转为unicode字符串失败
-
nResult = -1;
-
goto _exit_;
-
}
-
//转为UTF-8
-
nTragetLen = ::WideCharToMultiByte(CP_UTF8, 0, (LPWSTR)pUnicode, -1, if (0 == nTragetLen)
-
{
-
//获取UTF-8缓存大小失败
-
nResult = -1;
-
goto _exit_;
-
}
-
//判断此操作是否是获取缓存大小
-
if (NULL == szOut)
-
{
-
//返回大小
-
nResult = nTragetLen + 1;
-
goto _exit_;
-
}
-
pTragetData = new BYTE[nTragetLen + 1];
-
ZeroMemory(pTragetData, sizeof(BYTE)*(nTragetLen + 1));
-
nResult = ::WideCharToMultiByte(CP_UTF8, 0, (LPWSTR)pUnicode, -1, (char *)pTragetData, nTragetLen, NULL, NULL);
-
if (0 == nResult)
-
{
-
//将unicode字符串转为utf-8字符串失败
-
nResult = -1;
-
goto _exit_;
-
}
-
pTragetData[nTragetLen] = '\0';
-
lstrcpyA(szOut, (char*)pTragetData);
-
nResult = nTragetLen + 1;
-
_exit_:
-
if (NULL != pUnicode)
-
{
-
delete[] pUnicode;
-
pUnicode = NULL;
-
}
-
if (NULL != pTragetData)
-
{
-
delete[] pTragetData;
-
pTragetData = NULL;
-
}
-
#else
-
strcpy(szOut, szIn);
-
#endif// _DEBUG
-
return nResult;
-
}
-
int utf82char(const char *szIn, char *szOut){
-
int nResult = -1;
-
#ifdef _WIN32
-
int wcsLen = 0;
-
int ansLen = 0;
-
char *szAnsi = NULL;
-
wchar_t *wszString = NULL;
-
char *pszansi = NULL;
-
//判断参数有效性
-
if (NULL == szIn){
-
//参数错误
-
goto _exit_;
-
}
-
//获取所需要的空间大小
-
wcsLen = ::MultiByteToWideChar(CP_UTF8, 0, szIn, strlen(szIn), NULL, 0);
-
if (0 == wcsLen){
-
//获取UTF-8缓存长度失败
-
goto _exit_;
-
}
-
//分配空间要给'\0'留个空间,MultiByteToWideChar不会给'\0'空间
-
wszString = new wchar_t[wcsLen + 1];
-
ZeroMemory(wszString, sizeof(wchar_t)*(wcsLen + 1));
-
//转换为unicode
-
nResult = ::MultiByteToWideChar(CP_UTF8, 0, szIn, strlen(szIn), wszString, wcsLen);
-
if (0 == nResult){
-
//将UTF-8转换为unicode失败
-
nResult = -1;
-
goto _exit_;
-
}
-
//最后加上'\0'
-
wszString[wcsLen] = '\0';
-
//转换为ansi
-
//获取ansi长度
-
ansLen = ::WideCharToMultiByte( /*CP_ACP*/936, 0, wszString, wcslen(wszString), NULL, 0, NULL, NULL);
-
if (0 == ansLen){
-
//获取ANSI缓存长度失败
-
nResult = -1;
-
goto _exit_;
-
}
-
//判断是否获取缓存长度
-
if (NULL == szOut){
-
nResult = ansLen + 1;
-
goto _exit_;
-
}
-
//同上,分配空间要给'\0'留个空间
-
szAnsi = new char[ansLen + 1];
-
ZeroMemory(szAnsi, sizeof(char)*(ansLen + 1));
-
//转换
-
nResult = ::WideCharToMultiByte( /*CP_ACP*/936, 0, wszString, wcslen(wszString), szAnsi, ansLen, NULL, NULL);
-
if (0 == nResult){
-
//将UNICODE转换为ANSI失败
-
goto _exit_;
-
}
-
//最后加上'\0'
-
szAnsi[ansLen] = '\0';
-
strcpy(szOut, szAnsi);
-
nResult = ansLen + 1;
-
_exit_:
-
if (NULL != wszString){
-
delete[] wszString;
-
wszString = NULL;
-
}
-
if (NULL != szAnsi){
-
delete[] szAnsi;
-
szAnsi = NULL;
-
}
-
#else
-
strcpy(szOut, szIn);
-
#endif //_DEBUG
-
return nResult;
-
}
以上,转换的完整函数已经奉上,可供研究,可供使用,将其封装后,即可解决你的乱码问题了^_^.