生活随笔
收集整理的這篇文章主要介紹了
utf-8编码的字符串转成unicode(ucs-4)编码的字符串
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
本人第一篇原創博客,盡力把代碼注釋清楚,如有錯誤之處,敬請指出
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_t w = 0;mfchar_t err = '?';// 表轉碼錯誤int bytes = 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);}
}
總結
以上是生活随笔為你收集整理的utf-8编码的字符串转成unicode(ucs-4)编码的字符串的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。