在跨平台的开发中,字符串的转码显得相当重要,稍有不慎,将会出现乱码的情况,在这里,首先说一下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;}以上,转换的完整函数已经奉上,可供研究,可供使用,将其封装后,即可解决你的乱码问题了^_^.
觉得文章有帮助,请分享给其他小伙伴吧 ^-^.
识别左侧二维码关注公众号,接收更多技术文章。
新闻热点
疑难解答