首页 > 学院 > 开发设计 > 正文

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

2019-11-08 00:50:27
字体:
来源:转载
供稿:网友

在跨平台的开发中,字符串的转码显得相当重要,稍有不慎,将会出现乱码的情况,在这里,首先说一下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;}

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


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

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



发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表