IOS与Windows下字符集问题

由于之前手头上的事情比较多,一直没时间去理清思路去好好静下来去学习.关于之前完成的服务器端与客户端通信编码机的问题,一直都存在只是由于初期没打算做管理工具,相对于文字消息的发送的方面,服务器的工作也就只是一个转发而已.所以也就没去多考虑这个问题.直到后来需要向数据库,或者客户端主动发送写入的文字的时候,这个问题才不得不去花时间去解决.

大致介绍情况如下

1)ios与windows直接socket通信(使用boost单线程异步)

2)windows下通过mysql-connector对utf-8的数据库表进行操作

问题也是显而易见的,本身vs中未设置代码文件字符集,而选择的是多字符集.然后在ios(mysql)中相对应的字符集又与vs中使用的字符集不匹配,导致发送消息到ios上时,导致的中文乱码和在往mysql中插入中文时异常(incorrect string value异常),根据错误Incorrect string value: '\xF0\xA1\xA4\xA1\xEF\xBF...' for column 和 在ios上显示的乱码发现,问题的导致是由于不同字符编码集问题而导致的.

先简单看一下两端的编码

书面解释:

UTF-8:Unicode TransformationFormat-8bit,允许含BOM,但通常不含BOM。是用以解决国际上字符的一种多字节编码,它对英文使用8位(即一个字节),中文使用24为(三个字节)来编码。UTF-8包含全世界所有国家需要用到的字符,是国际编码,通用性强。UTF-8编码的文字可以在各国支持UTF8字符集的浏览器上显示。如,如果是UTF8编码,则在外国人的英文IE上也能显示中文,他们无需下载IE的中文语言支持包。 

GBK是国家标准GB2312基础上扩容后兼容GB2312的标准。GBK的文字编码是用双字节来表示的,即不论中、英文字符均使用双字节来表示,为了区分中文,将其最高位都设定成1。GBK包含全部中文字符,是国家编码,通用性比UTF8差,不过UTF8占用的数据库比GBD大。 

 

我的理解:

UTF-8使用3个字节来编码,而GBK(GB2312)使用2个字节来编码.同样的内容,显示的宽度改变,使相同中文字的不同的编码识别不出来.

 

解决办法:

1.对于mysql中可以通过在执行sql语句前进行执行"set names gbk"来告知db下面的语句使用gbk来编码,这样也就可以解决往数据库中插入中文的问题,但这样使用有一个副作用(可能是我的代码问题),这样执行后的结果可以很好的显示在数据库中,当取出后向IOS客户端发送时,在IOS上显示仍为乱码(直接在mysql中写入的不会出现这个问题).

2.对vs中本身要写入(或是操作的字符串string进行转码--最后会附上转码的代码),而关于这种转码在网上有比较多的资源,根据不同的操作系统环境也有不同的办法,由于服务器程序是部署在windows下的,我也就是使用了在windows下转换方法,而在linux下有iconv.h来解决问题(http://blog.csdn.net/jnbbwyth/article/details/6991371)

 

结论:

在windows下vs默认应该使用的是gbk(gb2132)编码,而在ios(mac)下xcode默认使用的utf-8.所以在相互通信或者操作的时候,注意转码.

 

暂时也就记录在这里了,很长一段时间没有更新了,自己太懒了.希望能慢慢的补上笔记了

 

CChineseCode.h
 1 #pragma once
 2 #include "comutil.h" 
 3 #pragma comment( lib, "comsuppw.lib" )
 4 #include <iostream>
 5 using namespace std;
 6 class CChineseCode
 7 {
 8 public:
 9     CChineseCode(void);
10     ~CChineseCode(void);
11     static void UTF_8ToUnicode(wchar_t* pOut,char *pText); // 把UTF-8转换成Unicode
12     static void UnicodeToUTF_8(char* pOut,wchar_t* pText); //Unicode 转换成UTF-8
13     static void UnicodeToGB2312(char* pOut,wchar_t uData); // 把Unicode 转换成 GB2312 
14     static void Gb2312ToUnicode(wchar_t* pOut,char *gbBuffer);// GB2312 转换成 Unicode
15     static void GB2312ToUTF_8(string& pOut,char *pText, int pLen);//GB2312 转为 UTF-8
16     static void UTF_8ToGB2312(string &pOut, char *pText, int pLen);//UTF-8 转为 GB2312
17 
18 };
CChineseCode.cpp
  1 #include "CChineseCode.h"
  2 
  3 
  4 CChineseCode::CChineseCode(void)
  5 {
  6 }
  7 
  8 
  9 CChineseCode::~CChineseCode(void)
 10 {
 11 }
 12 void CChineseCode::UTF_8ToUnicode(wchar_t* pOut,char *pText)
 13 {
 14     char* uchar = (char *)pOut;
 15 
 16     uchar[1] = ((pText[0] & 0x0F) << 4) + ((pText[1] >> 2) & 0x0F);
 17     uchar[0] = ((pText[1] & 0x03) << 6) + (pText[2] & 0x3F);
 18 
 19     return;
 20 }
 21 
 22 void CChineseCode::UnicodeToUTF_8(char* pOut,wchar_t* pText)
 23 {
 24     // 注意 WCHAR高低字的顺序,低字节在前,高字节在后
 25     char* pchar = (char *)pText;
 26 
 27     pOut[0] = (0xE0 | ((pchar[1] & 0xF0) >> 4));
 28     pOut[1] = (0x80 | ((pchar[1] & 0x0F) << 2)) + ((pchar[0] & 0xC0) >> 6);
 29     pOut[2] = (0x80 | (pchar[0] & 0x3F));
 30 
 31     return;
 32 }
 33 
 34 void CChineseCode::UnicodeToGB2312(char* pOut,wchar_t uData)
 35 {
 36     WideCharToMultiByte(CP_ACP,NULL,&uData,1,pOut,sizeof(wchar_t),NULL,NULL);
 37     return;
 38 }    
 39 
 40 void CChineseCode::Gb2312ToUnicode(wchar_t* pOut,char *gbBuffer)
 41 {
 42     ::MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,gbBuffer,2,pOut,1);
 43     return ;
 44 }
 45 
 46 void CChineseCode::GB2312ToUTF_8(string& pOut,char *pText, int pLen)
 47 {
 48     char buf[4];
 49     int nLength = pLen* 3;
 50     char* rst = new char[nLength];
 51 
 52     memset(buf,0,4);
 53     memset(rst,0,nLength);
 54 
 55     int i = 0;
 56     int j = 0;      
 57     while(i < pLen)
 58     {
 59         //如果是英文直接复制就可以
 60         if( *(pText + i) >= 0)
 61         {
 62             rst[j++] = pText[i++];
 63         }
 64         else
 65         {
 66             wchar_t pbuffer;
 67             Gb2312ToUnicode(&pbuffer,pText+i);
 68 
 69             UnicodeToUTF_8(buf,&pbuffer);
 70 
 71             unsigned short int tmp = 0;
 72             tmp = rst[j] = buf[0];
 73             tmp = rst[j+1] = buf[1];
 74             tmp = rst[j+2] = buf[2];    
 75 
 76             j += 3;
 77             i += 2;
 78         }
 79     }
 80     rst[j] = '\0';
 81 
 82     //返回结果
 83     pOut = rst;             
 84     delete []rst;   
 85 
 86     return;
 87 }
 88 
 89 void CChineseCode::UTF_8ToGB2312(string &pOut, char *pText, int pLen)
 90 {
 91     char * newBuf = new char[pLen];
 92     char Ctemp[4];
 93     memset(Ctemp,0,4);
 94 
 95     int i =0;
 96     int j = 0;
 97 
 98     while(i < pLen)
 99     {
100         if(pText[i] > 0)
101         {
102             newBuf[j++] = pText[i++];                       
103         }
104         else                 
105         {
106             WCHAR Wtemp;
107             UTF_8ToUnicode(&Wtemp,pText + i);
108 
109             UnicodeToGB2312(Ctemp,Wtemp);
110 
111             newBuf[j] = Ctemp[0];
112             newBuf[j + 1] = Ctemp[1];
113 
114             i += 3;    
115             j += 2;   
116         }
117     }
118     newBuf[j] = '\0';
119 
120     pOut = newBuf;
121     delete []newBuf;
122 
123     return; 
124 } 

 

posted @ 2013-12-11 22:46  xiaoEight  阅读(910)  评论(0编辑  收藏  举报