• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            colorful

            zc qq:1337220912

             

            nohup

            http://baike.baidu.com/view/1839401.htm

            posted @ 2012-07-24 14:55 多彩人生 閱讀(218) | 評論 (0)編輯 收藏

            編譯c文件出現undefined reference to `__gxx_personality_v0'

            在linux編寫程序如下
            QUOTE:
            #include
            #include
            #include
            int count=0;
            void ctrl_c_count(int);
            main()
            {
            int c;
            void (*old_handler)(int);
            old_handler=signal(SIGINT,ctrl_c_count);
            while((c=getchar()!='\n'))
            ;
            printf("Ctrl_C count=%d\n",count);
            signal(SIGINT,old_handler);

            }
            void ctrl_c_count(int i)
            {
            printf("Ctrl_C\n");
            count++;
            }

            這個程序的功能是研究signal函數的應用.
            signal 函數是用于設置信號量的處理函數為自定義的。
            SIGINT是用戶在終端上按下ctrl+c的而產生信號量
            它的系統默認的處理函數為終止正運行的進程
            現在把它改成按ctrl+c后,是全局變量count加1的操作
            當用戶在終端輸入回車后該進程結束。
            且又把SIGINT的處理函數為默認的。

            當我把上述程序保存為t.cpp時
            利用gcc -o t t.cpp
            產生如下錯誤
            /tmp/ccGsoxH2.o(.eh_frame+0x11): undefined reference to `__gxx_personality_v0'
            解決方法用 gcc -o t t.cpp -lstdc++
            為什么會出現這個錯誤:是因為你用gcc編譯.cpp文件.按系統默認.cpp文件是c++的文件格式
            另一個方法是用g++ -o t t.cpp 也是可以的
            還有一種方法是把文件保存為.c格式,反正里面全是c的代碼
            然后用gcc -o t t.c或者是g++ -o t t.c 都是OK的

            posted @ 2012-07-23 11:47 多彩人生 閱讀(1165) | 評論 (0)編輯 收藏

            Linux程序退出時的信號捕獲及處理

            1. #include <stdio.h>  
            2. #include <stdlib.h>  
            3. #include <string.h>  
            4. #include <sys/types.h>  
            5. #include <sys/stat.h>  
            6. #include <fcntl.h>  
            7. #include <unistd.h>  
            8. #include <signal.h>  
            1. // 程序退出時的函數操作  
            2. void test(int n,struct siginfo *siginfo,void *myact)  
            3. {  
            4.          printf("signal number:%d\n",n);/** 打印出信號值 **/  
            5.          printf("siginfo signo:%d\n",siginfo->si_signo); /** siginfo結構里保存的信號值 **/  
            6.          printf("siginfo errno:%d\n",siginfo->si_errno); /** 打印出錯誤代碼 **/  
            7.          printf("siginfo code:%d\n",siginfo->si_code);   /** 打印出出錯原因 **/  
            8.     exit(0);  
            9. }  
            10. int main(void)  
            11. {  
            12.          /** install signal use sigaction **/  
            13.          struct sigaction act;  
            14.          sigemptyset(&act.sa_mask);   /** 清空阻塞信號 **/  
            15.          act.sa_flags=SA_SIGINFO;     /** 設置SA_SIGINFO 表示傳遞附加信息到觸發函數 **/  
            16.          act.sa_sigaction=test;  
            17.          if(sigaction(SIGINT,&act,NULL) < 0)  
            18.          {  
            19.                  printf("install signal error\n");  
            20.          }  
            21.          while(1)  
            22.          {  
            23.                  sleep(1);  
            24.                  printf("wait for the signal\n");  
            25.          }  
            26. }  

            ///////////////////////////////////////////////////

          1. if (atexit(&cleanup)) //atexit現在不鼓勵用了,常用來做程序退出的后處理工作  
          2.     {  
          3.         fprintf(stderr, "cannot set exit function/n");  
          4.         return EXIT_FAILURE;  
          5.     }  
          6.     signal (SIGINT, &catch_int);  
          7.     signal (SIGTERM, &catch_term);  
          8. #ifdef __WIN32__  
          9.     signal (SIGBREAK, &catch_break);  
          10. #else  
          11.     signal (SIGHUP, &catch_hup);  
          12.     signal (SIGQUIT, &catch_quit);  
          13. #endif


          14. posted @ 2012-07-22 21:22 多彩人生 閱讀(1827) | 評論 (0)編輯 收藏

            控制臺多線程程序的結束方法

            比較不錯的方法是:
            1、在主線程(運行main函數的線程)中利用SetConsoleCtrlHandler注冊的控制事件處理函數(注意:這個函數將運行在另外的線程, 這點可用GetCurrentThreadId驗證之)7 ^& t" R+ _, D3 [. o
            2、控制事件產生后, 在控制線程(運行控制事件處理函數的線程)中設置標志量表明程序開始退出( 主線程檢測到標志量變化后將開始等待其余線程退出).控制線程開始等待工作者線程退出完成.
            3、各工作者線程檢測到標志量的變化, 退出. V& E; R' u) M% J  s
            4、控制線程退出
            主線程等待其余線程退出完成,退出3 f; C!

            posted @ 2012-07-22 21:21 多彩人生 閱讀(305) | 評論 (0)編輯 收藏

            std::map查詢效率優化

            0.現狀,數據是個xml文件,每個節點對應的結構體有10個成員變量,共有2000多條數據,用的std::map<string, struct>來保存,用map的find函數進行搜索時的效率極

             

            其低下,循環搜索30條數據竟然要20s+,搓死。

             

            1.為什么這么慢?

            最初懷疑是std::map的效率問題,正考慮是否使用std::hast_map來替換,于是了解下兩者之間的差別:

            std::map是個自平衡的紅黑樹,他的效率是平均的

            hash_map的是一個hash表,只要你的hash算法足夠唯一,你的效率可以達到O(1)

             

            翻書時大牛就在旁邊,就問了他,把情況和他一說。他立刻點名:

            用hash_map的效率確實會比map的高,但你的數據才2000多,兩者在這里數量級上的效率差異應該很小。主要的問題應該在于你的map,你的map的value不是一個指針

             

            ,而是一個大結構體,這會導致搜索時的內存頻繁被交換出去,因而導致效率低下。

             

            2.按照大牛的建議,修改,測試,消耗的時間由原來的20s+變成了0

            posted @ 2012-07-21 22:14 多彩人生 閱讀(4751) | 評論 (1)編輯 收藏

            使用 Boost 的Locale 進行字碼轉換

            這一篇會比較簡短一點,來大概提一下怎麼用 Boost C++ Libraries 的 Locale(官方文件)這個函式庫,來進行字碼的轉換。Locale 這個函式庫主要是提供 C++ 地區化(localization)的功能、並提供一些 Unicode 的處理能力;而 Heresy 在這邊只會針對字碼轉換的部分做說明。


            不過在使用時要注意的一點是,Locale 這個函式庫是在 1.48.0 才加入的,算是相當新的一個函示庫,所以要使用前必須要先確定自己使用的 Boost 的版本,確認是否在 1.48.0 以上;另外,他也是 Boost 中少數需要建置(build)的函式庫,並且可以搭配 ICU(官網)或 iconv(官網)來使用,有需要的話請參考官方的建置說明。(註 1、註 2)


            基本上,Locale 所提供的轉碼功能相當地簡單,官方文件請參考《Character Set Conversions》。


            基本上,Locale 所提供的字碼轉換都是函式的形式,而且這些函式都在 boost::locale::conv 這個 namespace 下,如果要使用的,則是要引入 boost/locale/encoding.hpp 這個 header 檔。


            而他提供用來轉碼的函式,則包括了:





            1. 不同字碼間的轉換-between()

              這個函式是用來將字串在不同的字碼間進行轉換用的,他的介面是:



              string between( string const &text,
              string const &to_encoding,
              string const &from_encoding,
              method_type how=default_method)

              他基本本上只能針對 string 做處理,不支援 wstring


              使用上相當簡單,第一個參數 text 就是要進行編碼轉換的字串,第二個參數 to_encoding 則是要轉換成什麼編碼,第三個參數 from_encoding 則是描述 text 是用哪種編碼(註 3)。


              而最後一個參數 how 則是 Locale 的一個列舉型別,代表在轉換失敗的時候,要做什麼處理;基本上只有兩個選項,skipstop,預設會是 skip,也就是無視無法轉換的字元、其他繼續處理。


              下面就次一個簡單的例子,他會把 source 這個字串從 BIG5 轉換到 UTF-8:



              string source = "....";
              string s = boost::locale::conv::between( source, "UTF-8", "BIG5" );

               




            2. 轉換到 UTF-to_utf()

              這個函式是將特定編碼的 string,轉換成 UTF 字串用的,它的介面基本上是:


              template<typename CharType>
              basic_string<CharType> to_utf( string const &text,
              string const &charset,
              method_type how )

              他除了可以輸出 string 之外,也可以支援輸出成 wstring。像下面的例子,就是把 sSource 這個 BIG-5 編碼的字串,依序轉換成 wstringstring 的字串。



              string sSource = "...";
              wstring ws = boost::locale::conv::to_utf<wchar_t>( sSource, "BIG5" );
              string ss = boost::locale::conv::to_utf<char>( sSource, "BIG5" );

               




            3. 從 UTF 轉成其他編碼-from_utf()

              這個函式和上面介紹的 to_utf() 相反,他是把 UTF 字串(stringwstring)、轉換為特定編碼的字串用的。它的介面是:


              template<typename CharType>
              string from_utf( basic_string<CharType> const &text,
              string const &charset,
              method_type how )

              他可以轉換 stringwstring 的字串,但是輸出一定是 string


              下面的例子,就是把 sSourcewSource 這兩個 UTF 字串,都轉換成 BIG-5 的 string 字串。



              string sSource = "...";
              wstring wSource = L"...";
              string ss1 = boost::locale::conv::from_utf( wSource, "BIG5" );
              string ss2 = boost::locale::conv::from_utf( sSource, "BIG5" );

               




            4. Unicode 之間的轉換-utf_to_utf()

              這個函式的目的,是在 UTF 的 string 字串和 wstring 字串之間做轉換;他的介面如下:


              template<typename CharOut,typename CharIn>
              basic_string<CharOut> utf_to_utf( basic_string<CharIn> const &str,
              method_type how )

              下面的例子,就是把型別是 stringsSource 轉換成 wstring、並把型別是 wstringwSource 轉換成 string 了~



              string sSource = "...";
              wstring wSource = L"...";
              wstring wStr = boost::locale::conv::utf_to_utf<wchar_t>( sSource );
              string sStr = boost::locale::conv::utf_to_utf<char>( wSource );





            這篇就寫到這裡了。基本上,Locale 所提供的字碼轉換的功能,在 Heresy 來看算是相當簡單好用的~至少和直接用 iconv 比起來,真的簡單不少…對於有需要在程式中進行字碼轉換的人來說,Heresy 是覺得可以試試看用 Boost 的 Locale 這個函式庫來做做看啦~


            而實際上,Locale 還有許多其他的功能,但是因為 Heresy 還用不太到,所以暫時就不研究了。

            不過另外 Heresy 覺得可能比較實用的,是他的《Messages Formatting (Translation) 》的部分~或許等有需要的時候,會來看看這一塊吧。




            附註:





            1. 在 Windows 平臺上,應該是可以不搭配 ICU 和 iconv 來使用的;但是在 POSIX 平臺上,則似乎一定要有 ICU 或 iconv 其中一個。




            2. Heresy 有試著想在 Windows 平臺上整合 ICU,不過感覺好像不是很成功…

              不過一個經驗是,似乎不能直接下載 ICU 的 binary 來作為 Boost 建置時的 ICU 路徑,而是需要下載 source code 來自己建置 ICU 才可以。但是雖然 Heresy 成功地讓 Boost 抓到 ICU 了,但是在試著轉碼的時候,他似乎還是去用 Windows 內建的 codepage、沒去用 ICU 的…




            3. 編碼基本上是直接以字串來做輸入,例如中文就是「BIG5」、Unicode 則是使用「UTF-8」; 另外也可以使用 std::locale參考)來作為指定編碼的參數。

              至於有支援那些編碼,則是要看是使用哪種字碼轉換的模組,例如有使用 iconv 和 ICU 的話,就是看 iconv 和 ICU 有支援什麼了~而在 Windows + MSVC 環境下,如果都沒用的話,Boost 會使用 Windows 內建的 code page 來做處理,列表可以參考 Boost 目錄下的 \libs\locale\src\encoding\wconv_codepage.ipp 這個檔案裡的 all_windows_encodings 這個陣列。




            4. 上述 Locale 所提供的轉換函式,都可以改用 char*wchar_t* 作為輸入的字串。




            5. FreeType 的 ft_encoding_unicode 可以使用 wsting 的 UTF 字串。




            6. 要在 standrad IO 輸出 wstring 這轉寬字元字串,不能使用 cout,而是要使用 wcout;而如果要輸出中文字串的話,則是需要透過 ostreamimbue() 這個函式,來做區域的設定。下面是一個例子:



              wstring wSource = L"中文";
              wcout.imbue( std::locale( "cht" ) );
              wcout << wSource << endl;

            posted @ 2012-07-18 19:07 多彩人生 閱讀(1520) | 評論 (0)編輯 收藏

            跨平臺的文字編碼轉換方法

            http://blog.csdn.net/serverxp/article/details/5538017

            最近在做一套跨平臺的短信收發開發程序,遇到了一個問題,那就是文字編碼轉換。在windowsg下的轉換有庫函數

            MultiByteToWideChar        WideCharToMultiByte,這二個,但是我要的是在linux機器下也可以正常使用,所以google了一天,發現了二個解決方案,一個是libiconv,一個就是ICU了,實際使用后,發現還是ICU更好用,下面是一個簡單的例子。

             

             

            1. #include <unicode/ucnv.h>  
            2. #ifdef _WIN32  
            3. #pragma comment(lib, "icuuc.lib")  
            4. #endif  
            5. //返回0為成功,錯誤代碼定義見后面  
            6. int convert(const char *    toConverterName,  
            7.     const char *    fromConverterName,  
            8.     char *  target,  
            9.     int32_t     targetCapacity,  
            10.     const char *    source,  
            11.     int32_t     sourceLength)  
            12. {  
            13.     UErrorCode  error = U_ZERO_ERROR;  
            14.     ucnv_convert(toConverterName,fromConverterName,target,  targetCapacity, source, sourceLength, &error );  
            15.     return error;  
            16. }  
            17. int _tmain(int argc, _TCHAR* argv[])  
            18. {  
            19.     wchar_t aaa[] = L"中國人的系統上123323";  
            20.     int alen = wcslen(aaa);  
            21.     int blen=alen*2+sizeof(int);  
            22.     char *abuff=new char[blen];  
            23.     int result = convert( "gb2312", "utf-16le", abuff, blen, (const char *)aaa, alen);  
            24.     cout << abuff << endl<<strlen(abuff)<<endl;  
            25.     delete []abuff;  
            26.     return 0;  

            posted @ 2012-07-18 17:31 多彩人生 閱讀(547) | 評論 (0)編輯 收藏

            Unicode和UTF-8之間的轉換詳解

            utf-8格式的xml指令,存儲在標準的std::string中,怎么把這個string轉化成普通的多字節的string
            utf-8編碼中漢字是3個字節或以上的,普通的多字節不是這樣表示的....

            #include <stdio.h>
            #include <string.h>

            // UTF-8的unicode表示方法到unicode的值轉換函數
            bool utf82unicode(unsigned int  byte[], int index, int count, int& unicode)
            {
            /*      for (int i=index; i < count; ++i) {
                            printf("byte[%d]:%0Xn",i, byte[i]);
                    }
                    printf("byte[index] & 0x80: %0Xn", byte[index] & 0x80);
                    printf("byte[index] & 0xE0: %0Xn", byte[index] & 0xE0);
                    printf("byte[index] & 0xF0: %0Xn", byte[index] & 0xF0);
            */
                    if (index >= count) return false;
                    if ( (byte[index] & 0x80) == 0x0)              //  一位
                    {
                            unicode = byte[index];
                    }
                    else if ((byte[index] & 0xE0) == 0xC0) // 兩位
                    {
                            if (index + 1 >= count ) return false;
                            unicode = (((int)(byte[index] & 0x1F)) < < 6)
                                    | (byte[ index + 1] & 0x3F);
                    }
                    else if ((byte[index] & 0xF0) == 0xE0) // 三位
                    {
                            if (index + 2 >= count) return false;
                            unicode = (((int)(byte[index] & 0x0F)) < < 12)
                                    | (((int)(byte[index  + 1] & 0x3F)) < < 6)
                                    | (byte[index + 2] & 0x3F);
                    }
                    else if ((byte[index] & 0xF8) == 0xF0) // 四位
                    {
                            if (index + 3 >= count) return false;
                            unicode = (((int)(byte[index] & 0x07)) < < 18)
                                    | (((int)(byte[index + 1] & 0x3F)) < < 12)
                                    | (((int)(byte[index + 2] & 0x3F)) < < 6)
                                    | (byte[index + 3] & 0x3F);
                    }
                    else if ((byte[index] & 0xFC) == 0xF8) // 五位
                    {
                            if (index + 4 >= count) return false;
                            unicode = (((int)(byte[index] & 0x03)) < < 24)
                                    | (((int)(byte[index + 1] & 0x3F)) < < 18)
                                    | (((int)(byte[index + 2] & 0x3F)) < < 12)
                                    | (((int)(byte[index + 3] & 0x3F)) < < 6)
                                    | (byte[index + 4] & 0x3F);
                    }
                    else if ((byte[index] & 0xFE) == 0xFC) // 六位
                    {
                            if (index + 5 >= count) return false;
                            unicode = (((int)(byte[index] & 0x01)) < < 30)
                                    | (((int)(byte[index + 1] & 0x3F)) < < 24)
                                    | (((int)(byte[index + 2] & 0x3F)) < < 18)
                                    | (((int)(byte[index + 3] & 0x3F)) < < 12)
                                    | (((int)(byte[index + 4] & 0x3F)) < < 6)
                                    | (byte[index + 5] & 0x3F);
                    }
                    else
                    {
                            return false;
                    }
                    return true;

            }

            然后unicode到多字節

            posted @ 2012-07-18 17:30 多彩人生 閱讀(278) | 評論 (0)編輯 收藏

            C++ Utf8字符轉換Gb312編碼

             
            http://cjmxp007.blog.163.com/blog/static/35473837201061541933667/

              1
             #ifndef TRANSFORM
              2 #define TRANSFORM
              3 #include <map>
              4 using namespace std;
              5 // 是否啟用map轉換,建議啟用
              6 // 使用map轉換的話,同一個常量字符串不會做兩次轉換
              7 #define TEST_TYPE_MAP
              8 
              9 typedef map<const char*const char*> strmap;
             10 
             11 class CUtf8String
             12 {
             13     public:
             14         inline CUtf8String(const char* gb2312)
             15         {
             16             m_bIsConst = true;
             17 #ifdef TEST_TYPE_MAP
             18             if (m[gb2312])
             19             {
             20                 m_utf8 = m[gb2312];
             21                 return ;
             22             }
             23 #endif
             24             int buffLen = 0;
             25             WCHAR wbuff[5120];
             26             MultiByteToWideChar(CP_ACP, 0, gb2312, -1, wbuff, 5120);
             27             buffLen = WideCharToMultiByte(CP_UTF8, 0, wbuff, -1, NULL, 000);
             28             m_utf8 = new char[buffLen+1];
             29             WideCharToMultiByte(CP_UTF8, 0, wbuff, -1, (LPSTR)m_utf8, buffLen, 00);
             30 #ifdef TEST_TYPE_MAP
             31             m[gb2312] = m_utf8;
             32 #endif
             33         }
             34 
             35         inline CUtf8String(char* gb2312)
             36         {
             37             m_bIsConst = false;
             38             int buffLen = 0;
             39             WCHAR wbuff[5120];
             40             MultiByteToWideChar(CP_ACP, 0, gb2312, -1, wbuff, 5120);
             41             buffLen = WideCharToMultiByte(CP_UTF8, 0, wbuff, -1, NULL, 000);
             42             m_utf8 = new char[buffLen+1];
             43             WideCharToMultiByte(CP_UTF8, 0, wbuff, -1, (LPSTR)m_utf8, buffLen, 00);
             44         }
             45 
             46         inline ~CUtf8String()
             47             {
             48 #ifndef TEST_TYPE_MAP
             49             if (m_utf8)
             50             {
             51                 delete m_utf8;
             52                 m_utf8 = 0;
             53             }
             54 #else
             55             if (!m_bIsConst)
             56                 {
             57                 if (m_utf8)
             58                     {
             59                     delete m_utf8;
             60                     m_utf8 = 0;
             61                     }
             62                 }
             63 #endif
             64             }
             65 
             66         inline operator char*()
             67             {
             68             return (char*)m_utf8;
             69             }
             70     private:
             71         const char* m_utf8;
             72         bool m_bIsConst;
             73 #ifdef TEST_TYPE_MAP
             74         static strmap m;
             75 #endif
             76 };
             77 
             78 class CGb2312String
             79     {
             80     public:
             81         inline CGb2312String(const char* utf8)
             82             {
             83 #ifdef TEST_TYPE_MAP
             84             if (m[utf8])
             85             {
             86                 m_gb2312 = 0;
             87                 m_gb2312 = m[utf8];
             88             }
             89 #endif
             90             int buffLen = 0;
             91             WCHAR wbuff[5120];
             92             MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wbuff, 5120);
             93             buffLen = WideCharToMultiByte(CP_ACP, 0, wbuff, -1, NULL, 000);
             94             m_gb2312 = new char[buffLen+1];
             95             WideCharToMultiByte(CP_ACP, 0, wbuff, -1, (LPSTR)m_gb2312, buffLen, 00);
             96 #ifdef TEST_TYPE_MAP
             97             m[utf8] = m_gb2312;
             98 #endif
             99         }
            100 
            101         inline CGb2312String(char* utf8)
            102         {
            103 #ifdef TEST_TYPE_MAP
            104             if (m[utf8])
            105             {
            106                 m_gb2312 = 0;
            107                 m_gb2312 = m[utf8];
            108             }
            109 #endif
            110             int buffLen = 0;
            111             WCHAR wbuff[5120];
            112             MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wbuff, 5120);
            113             buffLen = WideCharToMultiByte(CP_ACP, 0, wbuff, -1, NULL, 000);
            114             m_gb2312 = new char[buffLen+1];
            115             WideCharToMultiByte(CP_ACP, 0, wbuff, -1, (LPSTR)m_gb2312, buffLen, 00);
            116 #ifdef TEST_TYPE_MAP
            117             m[utf8] = m_gb2312;
            118 #endif
            119         }
            120 
            121         inline ~CGb2312String()
            122         {
            123 #ifndef TEST_TYPE_MAP
            124             if (m_gb2312)
            125                 {
            126                 delete m_gb2312;
            127                 m_gb2312 = 0;
            128                 }
            129 #endif
            130         }
            131 
            132         inline operator char*()
            133         {
            134             return (char*)m_gb2312;
            135         }
            136     private:
            137         const char* m_gb2312;
            138 #ifdef TEST_TYPE_MAP
            139         static strmap m;
            140 #endif
            141 };
            142 
            143 #ifdef TEST_TYPE_MAP
            144 strmap CUtf8String::m;
            145 strmap CGb2312String::m;
            146 #endif
            147 #endif
            148 
            149 
            150 //===================無聊的分割線==========================
            151 
            152 #define U   (CUtf8String)
            153 
            154 #define W   (CGb2312String)
            155 
            156 // 使用方法
            157 int main(int argc, char* argv[])
            158 {
            159     // 打印出亂碼即為UTF8的編碼,方便吧。C++還是確實很強悍的
            160     printf("%s", U"你好中國!");
            161 }

            posted @ 2012-07-18 17:24 多彩人生 閱讀(1140) | 評論 (0)編輯 收藏

            Unicode和UTF-8之間的轉換詳解

            ps. 轉的,代碼上有錯誤的,沒仔細看,只看了下思路思想,很不錯,特別鄙視那種死咬人家錯誤不放的人,嗎的,誰寫代碼沒個錯誤,誰能代碼一寫出來就不用改不用來回推敲. 人家目的是向你介紹思想,思想你明白了不就行了.
            =======================================================
            最近在用VC++開發一個小工具,平時用慣了.NET,用起VC++最郁悶的就是字符串 處理。當然最最讓人難于琢磨的就是字符集,編碼之間的轉換。通過這幾天的研究,終于明白了Unicode和UTF-8之間編碼的區別。Unicode是一 個字符集,而UTF-8是Unicode的其中一種,Unicode是定長的都為雙字節,而UTF-8是可變的,對于漢字來說Unicode占有的字節比 UTF-8占用的字節少1個字節。Unicode為雙字節,而UTF-8中漢字占三個字節。
                                   
            網魂小兵 http://xdotnet.cnblogs.com
                UTF-8編碼字符理論上可以最多到6個字節長,然而16位BMP(
            Basic Multilingual Plane)字符最多只用到3字節長。下面看一下UTF-8編碼表:

                    U-00000000 - U-0000007F: 0xxxxxxx
                    U-00000080 - U-000007FF: 110xxxxx 10xxxxxx
                    U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
                    U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
                    U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
                    U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx


                xxx 的位置由字符編碼數的二進制表示的位填入, 越靠右的 x 具有越少的特殊意義,只用最短的那個足夠表達一個字符編碼數的多字節串。 注意在多字節串中, 第一個字節的開頭"1"的數目就是整個串中字節的數目。而第一行中以0開頭,是為了兼容ASCII編碼,為一個字節,第二行就為雙字節字符串,第三行為3 字節,如漢字就屬于這種,以此類推。(個人認為:其實我們可以簡單的把前面的1的個數看成字節數)
                                     網魂小兵 http://xdotnet.cnblogs.com
                為了要將Unicode轉換為UTF-8,當然要知道他們的區別到底在什么地方。下面來看一下,在Unicode中的編碼是怎樣轉換成UTF-8的,在UTF-8中,如果一個字符的字節小于0x80(128)則為ASCII字符,占一個字節,可以不用轉換,因為UTF-8兼容ASCII編碼。假如在Unicode中漢字“你”的編碼為“u4F60”,把它轉換為二進制為100111101100000,然后按照UTF-8的方法進行轉換。可以將Unicode二進制從地位往高位取出二進制數字,每次取6位,如上述的二進制就可以分別取出為如下所示的格式,前面按格式填補,不足8位用0填補。

                  
                       unicode:  100111101100000                  4F60

                       utf-8:    11100100,10111101,10100000       E4BDA0


                從上面就可以很直觀的看出Unicode到UTF-8之間的轉換,當然知道了UTF-8的格式后,就可以進行逆運算,就是按照格式把它在二進制中的相應位置上取出,然后在轉換就是所得到的Unicode字符了(這個運算可以通過“位移”來完成)。
                                 
            網魂小兵 http://xdotnet.cnblogs.com
                如上述的“你”的轉換,由于其值大于0x800小于0x10000,因此可以判斷為三字節存儲,則最高位需要向右移“12”位再根據三字節格式的最高位為 11100000(0xE0)求或(|)就可以得到最高位的值了。同理第二位則是右移“6”位,則還剩下最高位和第二位的二進制值,可以通過與 111111(0x3F)求按位于(&)操作,再和11000000(0x80)求或(|)。第三位就不用移位了,只要直接取最后六位(與 111111(ox3F)取&),在與11000000(0x80)求或(|)。OK了,轉換成功!在VC++中的代碼如下所示(Unicode到UTF-8的轉換)。

                    1 const wchar_t pUnicode = L"";
                    2 char utf8[3+1];
                    3 memset(utf8,0,4);
                    4 utf8[0= 0xE0|(pUnicode>>12);
                    5 utf8[1= 0x80|((pUnicode>>6)&0x3F);
                    6 utf8[2= 0x80|(pUnicode&0x3F);
                    7 utf8[3= "\0";
                    8 //char[4]就是UTF-8的字符“你”了。

                當然在UTF-8到Unicode的轉換也是通過移位等來完成的,就是把UTF-8那些格式相應的位置的二進制數給揪出來。在上述例子中“你”為三個字節,因此要每個字節進行處理,有高位到低位進行處理。在UTF-8中“你”為
            11100100,10111101,10100000。從高位起即第一個字節11100100就是把其中的"0100"給取出來,這個很簡單只要和11111(0x1F)取與(&),由三字節可以得知最到位肯定位于12位之前,因為每次取六位。所以還要將得到的結果左移12位,最高位也就這樣完成了0100,000000,000000。而第二位則是要把“111101”給取出來,則只需將第二字節10111101 和111111(0x3F)取與(&)。在將所得到的結果左移6位與最高字節所得的結果取或(|),第二位就這樣完成了,得到的結果為 0100,111101,000000。以此類推最后一位直接與111111(0x3F)取與(&),再與前面所得的結果取或(|)即可得到結果 0100,111101,100000。OK,轉換成功!在VC++中的代碼如下所示(UTF-8Unicode的轉換)。

                1 //UTF-8格式的字符串
                2 const char* utf8 = "";
                3 wchar_t unicode;
                4 unicode = (utf8[0& 0x1F<< 12;
                5 unicode |= (utf8[1& 0x3F<< 6;
                6 unicode |= (utf8[2& 0x3F);
                7 //unicode is ok!
                                        網魂小兵 http://xdotnet.cnblogs.com
                當然在編程過程中不可能只轉換一個字符,這里需要注意的是字符的長度一定要算清楚,不然會帶來...以上就是我這幾天研究的結果,至于Unicode的轉換為GB2312在MFC中Windows有自帶的API(WideCharToMultiByte)可以轉換。這樣也就能夠將UTF-8格式轉換為GB2312了,這里就不再贅述,如果大家有更好的方法希望指教。

            posted @ 2012-07-18 14:50 多彩人生 閱讀(185) | 評論 (0)編輯 收藏

            僅列出標題
            共25頁: First 10 11 12 13 14 15 16 17 18 Last 

            導航

            統計

            常用鏈接

            留言簿(3)

            隨筆分類

            隨筆檔案

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            久久久无码一区二区三区| 婷婷久久综合| av无码久久久久不卡免费网站 | 久久午夜羞羞影院免费观看| 色婷婷综合久久久中文字幕| 一级做a爱片久久毛片| 亚洲国产精品无码久久久久久曰 | 久久亚洲电影| 久久婷婷五月综合色高清| 93精91精品国产综合久久香蕉| 亚洲日本久久久午夜精品| 国产精品视频久久久| 久久久精品久久久久影院| 国产精品久久久久9999| 一本久久综合亚洲鲁鲁五月天| 久久久精品免费国产四虎| 中文精品久久久久人妻不卡| 久久久久99精品成人片三人毛片 | 久久久无码一区二区三区| 欧美午夜精品久久久久久浪潮| 久久亚洲私人国产精品| 精品久久久一二三区| 久久亚洲中文字幕精品一区四 | 国内精品久久久久伊人av| 波多野结衣久久精品| 久久国产成人午夜aⅴ影院| 久久96国产精品久久久| 日韩av无码久久精品免费| 久久人人爽人人人人片av| 久久嫩草影院免费看夜色| 7777久久亚洲中文字幕| 人妻无码αv中文字幕久久琪琪布 人妻无码久久一区二区三区免费 人妻无码中文久久久久专区 | 无码人妻久久一区二区三区免费丨 | 天堂无码久久综合东京热| 久久精品国产第一区二区| 999久久久免费国产精品播放| 狠狠色丁香久久综合婷婷| 国产精品毛片久久久久久久| 久久精品国产亚洲网站| 久久国产福利免费| 一级女性全黄久久生活片免费 |