不同字符集之间的操作

下面要讲的字符集主要是下面几种:UTF8,UTF16,GB,ASCII。使用该字符集存储的文件对应的也有点特殊处理,下面会讲到的。对于文件的格式,可以采用Uedit来查看二进制码,下面用存储“abc”的文本文档举例。

ASCII是最普遍是用的一种字符集了,因为在Windows平台上的文本文档默认的都是这个字符集,所有的字符都用单字来表示。没有什么可以讲,就是存储每一个字符对应的ASCII码,文件格式也没有特殊。如下所示

后面的三种格式,可以广义的称为unicode的格式。因为双字节或多个字节来标示一个字符的。当为单纯的字符时,这是文件的内容为

可以看到文件的开头会有两个字节的文件类型的标识符FF FE,这说明这个文件的存储格式是Unicode的。每一个字符的UTF8表示格式都是后面补充00。不同的文件系统的存储方式不尽相同,如果文件的标示符为“FE FF”,那么对应的字母a的表示将是“00 61”了。因为有00的存在,在做文件读取的时候如果readline的话(按照string的风格读取),肯定会在遇到00就认为是“/0”,就结束了。所以Unicode的文件不能简单的读取,只能以二进制的方式读取。

对于GB主要汉字的一种字符集。有自己的对应的字符集。它肯定是双字表示的,无论是在ASCII格式还是UTF8格式的文件中。例如:“你好ABC”在unicode文件格式中

可以看到,汉字就不会简单的像字符一样补充00。至于为什么“联通”会在记事本中保存后显示乱码的原因,大家可以看看二进制码就知道了,因为他的GB字符集对应的正好是“FFFE”,记事本以为它是Unicode的文件,所以就错误的显示了。

UTF8的应用最为广泛,在数据的网络传输的过程中,大量使用UTF8。那么UTF8和ASCII相互转化很简单

//UTF8 to ASCII

  DWORD dwNum = WideCharToMultiByte(CP_ACP,0,(LPCWSTR)data+1,-1,NULL,0,NULL,FALSE);
  psText      = new char[dwNum];
  if(!psText)
  {
   delete []psText;
  }
  int len = wcslen((LPCWSTR)data+1);  //这里用的不是strlen,大小很重要
  WideCharToMultiByte(CP_ACP,0,(LPCWSTR)data+1,-1,psText,dwNum,NULL,FALSE);

//ASCII to UTF8

  DWORD dwNum;
  dwNum = MultiByteToWideChar (CP_ACP,  0 , szXML, -1, NULL, 0);
  char *psText;
  psText = new char[dwNum*2];  //注意留足够的空间
  if(!psText)
  {
   delete []psText;
  }
  printf("szXML");
  MultiByteToWideChar (CP_ACP, 0 ,szXML,-1,(unsigned short *)psText,dwNum);

 

如果是GB,那么转化的方式稍微复杂一点。要将GB先转化为UTF16,然后转化为UTF8,函数与上面相同

const char *gbks;

unsigned short *wbuf;   //这里不是char,是unsigned short,unsigned short 其实== w_tchar

 int wbuf_len;

gbks_len = strlen(gbks);
 
 MultiByteToWideChar(0, 0, gbks, gbks_len, wbuf, wbuf_len); //GB to UTF16

WideCharToMultiByte(CP_UTF8, 0, ucs, ucs_len, (char *)cbuf, cbuf_len, NULL, NULL); //UTF16 to UTF8

程序从我以前的例子中节选,不一定可以调试,^_^。但是方法大致就是这样子的。

另外还有文件格式中,dos格式和Unix格式也不相同,大致的驱别在于dos的换行为/n,Unix的为/r/n,很多国际标准的协议文本中都会要求是后者。

提醒文件写成Unicode,记得加上文件标示头“FF FE”

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值