解决你的乱码难题(Qt转码与char和utf8的互转)

解决你的乱码难题(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类型:

  1. int char2utf8(const char *szIn, char *szOut){

  2. int nResult = -1;

  3. #ifdef _WIN32

  4. int nLen = 0;

  5. int nUnicodeLen = 0;

  6. wchar_t *pUnicode = NULL;

  7. BYTE *pTragetData = NULL;

  8. int nTragetLen = 0;

  9.  
  10. //校验参数有效性

  11. if (NULL == szIn)

  12. {

  13. //参数错误

  14. goto _exit_;

  15. }

  16.  
  17. //转换为unicode

  18. nLen = lstrlenA(szIn);

  19. nUnicodeLen = ::MultiByteToWideChar(CP_ACP, 0, szIn, -1, NULL, 0);

  20. if (nUnicodeLen == 0)

  21. {

  22. //获取unicode缓存长度失败

  23. goto _exit_;

  24. }

  25. pUnicode = new wchar_t[nUnicodeLen + 1];

  26. ZeroMemory(pUnicode, (nUnicodeLen + 1)*sizeof(wchar_t));

  27. nResult = ::MultiByteToWideChar(CP_ACP, 0, szIn, -1, (LPWSTR)pUnicode, nUnicodeLen);

  28. if (0 == nResult)

  29. {

  30. //将源字符串转为unicode字符串失败

  31. nResult = -1;

  32. goto _exit_;

  33. }

  34.  
  35. //转为UTF-8

  36. nTragetLen = ::WideCharToMultiByte(CP_UTF8, 0, (LPWSTR)pUnicode, -1, if (0 == nTragetLen)

  37. {

  38. //获取UTF-8缓存大小失败

  39. nResult = -1;

  40. goto _exit_;

  41. }

  42. //判断此操作是否是获取缓存大小

  43. if (NULL == szOut)

  44. {

  45. //返回大小

  46. nResult = nTragetLen + 1;

  47. goto _exit_;

  48. }

  49. pTragetData = new BYTE[nTragetLen + 1];

  50. ZeroMemory(pTragetData, sizeof(BYTE)*(nTragetLen + 1));

  51. nResult = ::WideCharToMultiByte(CP_UTF8, 0, (LPWSTR)pUnicode, -1, (char *)pTragetData, nTragetLen, NULL, NULL);

  52. if (0 == nResult)

  53. {

  54. //将unicode字符串转为utf-8字符串失败

  55. nResult = -1;

  56. goto _exit_;

  57. }

  58. pTragetData[nTragetLen] = '\0';

  59. lstrcpyA(szOut, (char*)pTragetData);

  60. nResult = nTragetLen + 1;

  61.  
  62. _exit_:

  63. if (NULL != pUnicode)

  64. {

  65. delete[] pUnicode;

  66. pUnicode = NULL;

  67. }

  68.  
  69. if (NULL != pTragetData)

  70. {

  71. delete[] pTragetData;

  72. pTragetData = NULL;

  73. }

  74. #else

  75. strcpy(szOut, szIn);

  76. #endif// _DEBUG

  77. return nResult;

  78. }

  79. int utf82char(const char *szIn, char *szOut){

  80. int nResult = -1;

  81. #ifdef _WIN32

  82. int wcsLen = 0;

  83. int ansLen = 0;

  84. char *szAnsi = NULL;

  85. wchar_t *wszString = NULL;

  86. char *pszansi = NULL;

  87. //判断参数有效性

  88. if (NULL == szIn){

  89. //参数错误

  90. goto _exit_;

  91. }

  92. //获取所需要的空间大小

  93. wcsLen = ::MultiByteToWideChar(CP_UTF8, 0, szIn, strlen(szIn), NULL, 0);

  94. if (0 == wcsLen){

  95. //获取UTF-8缓存长度失败

  96. goto _exit_;

  97. }

  98.  
  99. //分配空间要给'\0'留个空间,MultiByteToWideChar不会给'\0'空间

  100. wszString = new wchar_t[wcsLen + 1];

  101. ZeroMemory(wszString, sizeof(wchar_t)*(wcsLen + 1));

  102.  
  103. //转换为unicode

  104. nResult = ::MultiByteToWideChar(CP_UTF8, 0, szIn, strlen(szIn), wszString, wcsLen);

  105. if (0 == nResult){

  106. //将UTF-8转换为unicode失败

  107. nResult = -1;

  108. goto _exit_;

  109. }

  110. //最后加上'\0'

  111. wszString[wcsLen] = '\0';

  112. //转换为ansi

  113. //获取ansi长度

  114. ansLen = ::WideCharToMultiByte( /*CP_ACP*/936, 0, wszString, wcslen(wszString), NULL, 0, NULL, NULL);

  115. if (0 == ansLen){

  116. //获取ANSI缓存长度失败

  117. nResult = -1;

  118. goto _exit_;

  119. }

  120.  
  121. //判断是否获取缓存长度

  122. if (NULL == szOut){

  123. nResult = ansLen + 1;

  124. goto _exit_;

  125. }

  126. //同上,分配空间要给'\0'留个空间

  127. szAnsi = new char[ansLen + 1];

  128. ZeroMemory(szAnsi, sizeof(char)*(ansLen + 1));

  129.  
  130. //转换

  131. nResult = ::WideCharToMultiByte( /*CP_ACP*/936, 0, wszString, wcslen(wszString), szAnsi, ansLen, NULL, NULL);

  132. if (0 == nResult){

  133. //将UNICODE转换为ANSI失败

  134. goto _exit_;

  135. }

  136.  
  137. //最后加上'\0'

  138. szAnsi[ansLen] = '\0';

  139. strcpy(szOut, szAnsi);

  140. nResult = ansLen + 1;

  141.  
  142. _exit_:

  143. if (NULL != wszString){

  144. delete[] wszString;

  145. wszString = NULL;

  146. }

  147. if (NULL != szAnsi){

  148. delete[] szAnsi;

  149. szAnsi = NULL;

  150. }

  151. #else

  152. strcpy(szOut, szIn);

  153. #endif //_DEBUG

  154. return nResult;

  155. }

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

猜你喜欢

转载自blog.csdn.net/hktkfly6/article/details/82969743