在跨平臺的開發中,字符串的轉碼顯得相當重要,稍有不慎,將會出現亂碼的情況,在這裏,首先說一下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;
}
以上,轉換的完整函數已經奉上,可供研究,可供使用,將其封裝後,即可解決你的亂碼問題了^_^.
覺得文章有幫助,請分享給其他小夥伴吧 ^-^.
識別左側二維碼關注公衆號,接收更多技術文章。