解決你的亂碼難題(Qt轉碼與char和utf8的互轉)

分類:編程 時間:2017-02-22

在跨平臺的開發中,字符串的轉碼顯得相當重要,稍有不慎,將會出現亂碼的情況,在這裏,首先說一下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 = http://www.ithao123.cn/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 = http://www.ithao123.cn/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;
}

以上,轉換的完整函數已經奉上,可供研究,可供使用,將其封裝後,即可解決你的亂碼問題了^_^.



覺得文章有幫助,請分享給其他小夥伴吧 ^-^.

識別二維碼關註,接收更多技術文章。?




Tags: 字符串 中文 開發 如何

文章來源:


ads
ads

相關文章
ads

相關文章

ad