解决你的乱码难题(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;
}

以上,转换的完整函数已经奉上,可供研究,可供使用,将其封装后,即可解决你的乱码问题了^_^.



觉得文章有帮助,请分享给其他小伙伴吧 ^-^.

识别左侧二维码关注公众号,接收更多技术文章。



展开阅读全文

没有更多推荐了,返回首页