现在的位置: 首页 > 综合 > 正文

c++中unicode utf8, gb2312还有url_encoding

2013年02月15日 ⁄ 综合 ⁄ 共 4677字 ⁄ 字号 评论关闭
 我这里说的unicode指的是在windows下用wchar_t表示的那个unicode, 也就是L"xxx"中表示的那个unicode,也就是在编译选项里面用unicode 并且_T("XXX") 中的unicode
下面的代码
TCHAR english[] = _T("Hello");
TCHAR chinese[] 
= _T("你好");
char chineseA[] = "你好";
char enchlishA[] = "hello";
wchar_t chineseW[] 
= L"你好";
wchar_t englishW[] 
= L"hello"

在visual c++中,根本不管utf8, 在没有定义unicode时候编译一下代码
TCHAR和_T就翻译成为了普通的char和“”
在定义了unicode的时候
TCHAR和_T就翻译成为了wchar_t和L""
其中char中指定中文的时候,中文使用gb2312编码中文占2个字节,而指定英文的时候,英文占1个字节,是标准的ascII, 但是gb2312编码国际化不好,就是说各国语言的编码可能有重叠的部分,就是说2字节的东西,同一个2字节的数字可能对应不同的编码中的不同的符号所以才出现了乱码
所以就有了unicode了
wchar_t中无论中文英文(还有日文等等)都是同一作为2个字节,好处在于无论中文英文日文一个字符都有一个统一的不同的数字,(unicode = unique code咯~~)其实wchar_t的本质上就是unsigned short

虽然unicode解决了统一编码的问题,但是不好啊,因为他定长的,就好象我们数据压缩中的如果用定长编码
的效率肯定不如变长编码高了,所以utf8就产生了
utf8本质上就是unicode的编程编码,具体的编码解我们可以一下的link
http://zhidao.baidu.com/question/2692826.html
而url_encoding是在网络传输中为了避开一些特殊的字符(比如&,/n等等),所以使用的编码方式,他是在utf8或者unicode智商的编码,就是说无论我们在网络上传送的是utf8或者是unicode我们都可以通过url_encoding把他在发送端编码并且在接收端解码,(当然了我们也可以用url_encoding来传送2进制流)url_encoding每8位编码一次(就是吧除了a~z,A~Z,1~9还有几个其他符号(我这里说的是转换成为int的字符)转换成%XX的16进制表达方式

也就是说utf8 和 unicode, gb2132是平行的概念,这几个概念是相对的,是在操作系统层的编码,而url_encoding是在这2者上一层次的编码,用来把某段数据数据在网络上发送出去。是在网络层的编码(这段数据可以是utf-8也可以是unicode,也可以是gb2312也可以是其他的如gbk, jp等等的编码)

关于url_encoding我们可以看
http://www.albionresearch.com/misc/urlencode.php
utf8, unicode, urlencoding转换请看代码(unicode的urlencoding我就不想写了。懒得写了, gb2312转uicode可以通过bstr_t类转换,windows也带有了相应的api)
.h文件

class EncodingConvertor  {
 
public:
  EncodingConvertor(
void);
 
public:
  
~EncodingConvertor(void);
 
public:
  
bool Unicode2UTF8(const wchar_t *input_unicode,char ** p_output_utf8,unsigned long *length);

  
bool UTF82Unicode(const char *input_utf8, wchar_t ** p_output_unicode, unsigned long *length);

  
bool UTF82UrlEncode(const char* input_utf8, char ** p_url_encode, unsigned long *length);
}
;

.cpp文件

include <stdlib.h>
#include 
"EncodingConvertor.h"


EncodingConvertor::EncodingConvertor(
void{
}


EncodingConvertor::
~EncodingConvertor(void{
}


bool EncodingConvertor::Unicode2UTF8(const wchar_t *input_unicode,
                                     
char ** p_output_utf8,
                                     unsigned 
long *length) {
  
if (input_unicode == NULL) {
    
return true;
  }

  
int size_d = 8;
  
int buffer_size = 0;

  
const wchar_t* p_unicode = input_unicode;
  
// count for the space need to allocate
  wchar_t w_char;
  
do {
    w_char 
= *p_unicode;
    
if (w_char < 0x80{
      
// utf char size is 1
      buffer_size += 1;
    }
 else if (w_char < 0x800{
      
// utf char size is 2
      buffer_size += 2;
    }
 else if (w_char < 0x10000{
      
// utf char size is 3
      buffer_size += 3;
    }
 else if (w_char < 0x200000{
      
// utf char size is 4
      buffer_size += 4;
    }
 else if (w_char < 0x4000000{
      
// utf char size is 5
      buffer_size += 5;
    }
 else {
      
// utf char size is 6
      buffer_size += 6;
    }

    p_unicode
++;
  }

  
while (w_char != static_cast<char>(0));
  
// allocate the memory
  char* utf8 = new char[buffer_size];

  p_unicode 
= input_unicode;
  
int index_buffer = 0;
  
// do the conversion
  do {
    w_char 
= *input_unicode;  // the unicode char current being converted
    input_unicode++;

    
if (w_char < 0x80{
      
// length = 1;
      utf8[index_buffer++= static_cast<char>(w_char);
    }
 else if (w_char < 0x800{
    
// length = 2;
      utf8[index_buffer++= 0xc0 | (w_char >> 6);
      utf8[index_buffer
++= 0x80 | (w_char & 0x3f);
    }
 else if (w_char < 0x10000{
      
// length = 3;
      utf8[index_buffer++= 0xe0 | (w_char >> 12);
      utf8[index_buffer
++= 0x80 | ((w_char >> 6& 0x3f);
      utf8[index_buffer
++= 0x80 | (w_char & 0x3f);
    }
 else if (w_char < 0x200000{
      
// length = 4;
      utf8[index_buffer++= 0xf0 | (static_cast<int>(w_char) >> 18);
      utf8[index_buffer
++= 0x80 | ((w_char >> 12& 0x3f);
      utf8[index_buffer
++= 0x80 | ((w_char >> 6& 0x3f);
      utf8[index_buffer
++= 0x80 | (w_char & 0x3f);
    }
 else if (w_char < 0x4000000{
      
// length = 5
      utf8[index_buffer++= 0xf8| (static_cast<int>(w_char) >> 24);
      utf8[index_buffer
++= 0x80 | ((static_cast<int>(w_char) >> 18& 0x3f);
      utf8[index_buffer
++= 0x80 | ((w_char >> 12& 0x3f);
      utf8[index_buffer
++= 0x80 | ((w_char >> 6& 0x3f);
      utf8[index_buffer
++= 0x80 | (w_char & 0x3f);
    }
 else {  // if(wchar >= 0x4000000)
      
// all other cases length = 6
      utf8[index_buffer++= 0xfc | (static_cast<int>(w_char) >> 30);
      utf8[index_buffer
++= 0x80 | ((static_cast<int>(w_char) >> 24& 0x3f);
      utf8[index_buffer
++= 0x80 | ((static_cast<int>(w_char) >> 18& 0x3f);
      utf8[index_buffer
++= 0x80 | ((w_char >> 12& 0x3f);
      utf8[index_buffer
++= 0x80

抱歉!评论已关闭.