utf-8编码的字符串转成unicode(ucs-4)编码的字符串

来源:互联网 发布:5g网络建设 编辑:程序博客网 时间:2024/06/06 02:48

本人第一篇原创博客,尽力把代码注释清楚,如有错误之处,敬请指出微笑


typedef unsigned int                mfchar_t;// 无符号的4字节,用于容纳UCS-4的一个字符typedef std::basic_string<mfchar_t> mfstring;// 自定义的UCS-4字符串// 把utf-8编码的字符串转换成UCS-4编码的字符串void DB_Mofify_Handler::utf8ToWS(const string& src, mfstring& dest){mfchar_tw= 0;mfchar_terr= '?';// 表转码错误intbytes= 0;  // 表剩余要处理的字节数for (size_t i = 0; i < src.length(); i++){unsigned char c = (unsigned char)src[i];if (c <= 0x7f)// <= 0x0111 1111(即127)的说明是ascii码{// 若bytes不为0,说明出错,因为ascii码的utf-8编码只占一个字节if (bytes){dest.push_back(err); bytes = 0;}// 将字符压入队列dest.push_back((mfchar_t)c);}else if (c <= 0xbf)// <= 0x1011 1111,说明是多字节的utf-8编码的第2,3,4,5,6字节{// 既然是2,3,4,5,6字节,bytes必不为0,否则出错if (bytes){// 取出c的后六位,将w左移6位,做或预算,赋值给w,这样w就融合了c的后6位w = ( (w << 6) | (c & 0x3f) );// 字节数减1,因为本字节已经融合完毕bytes--;// 若后面没有字节数了,说明字节数融合完毕,成为一个完整的ucs-4的字符了,压入队列if (bytes == 0){    dest.push_back(w);}}else{dest.push_back(err); // 出错}}else if (c <= 0xdf)// <= 0x1101 1111,说明是2字节的utf-8编码的第一个字节{bytes = 1;// 标记后面还有1个字节,下面类似w = c & 0x1f;// 取出后5位,注意是赋值操作,所以w的高位都将赋值为0。然后将 w 与后面字节的后六位融合即可,下面类似}else if (c <= 0xef)// <= 0x1110 1111,说明是3字节的utf-8编码的第一个字节{bytes = 2;w = c & 0x0f;// 取出后4位}else if (c <= 0xf7)// <= 0x1111 0111,说明是4字节的utf-8编码的第一个字节{bytes = 3;w = c & 0x07;// 取出后3位}else if (c <= 0xfb)// <= 0x1111 1011,说明是5字节的utf-8编码的第一个字节{bytes = 4;w = c & 0x03;// 取出后2位}else if (c <= 0xfd)// <= 0x1111 1101,说明是6字节的utf-8编码的第一个字节{bytes = 5;w = c & 0x01;// 取出后1位}else                // > 0x1111 1101的是出错,因utf-8最多6个字节{dest.push_back(err);bytes = 0;}}if (bytes) {dest.push_back(err);}}




0 0