colorful

zc qq:1337220912

 

nohup

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

posted @ 2012-07-24 14:55 多彩人生 阅读(193) | 评论 (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 多彩人生 阅读(1102) | 评论 (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. }  

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

  • if (atexit(&cleanup)) //atexit现在不鼓励用了,常用来做程序退出的后处理工作  
  •     {  
  •         fprintf(stderr, "cannot set exit function/n");  
  •         return EXIT_FAILURE;  
  •     }  
  •     signal (SIGINT, &catch_int);  
  •     signal (SIGTERM, &catch_term);  
  • #ifdef __WIN32__  
  •     signal (SIGBREAK, &catch_break);  
  • #else  
  •     signal (SIGHUP, &catch_hup);  
  •     signal (SIGQUIT, &catch_quit);  
  • #endif


  • posted @ 2012-07-22 21:22 多彩人生 阅读(1804) | 评论 (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 多彩人生 阅读(289) | 评论 (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 多彩人生 阅读(4557) | 评论 (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 多彩人生 阅读(1399) | 评论 (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 多彩人生 阅读(483) | 评论 (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 多彩人生 阅读(259) | 评论 (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 多彩人生 阅读(1125) | 评论 (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 多彩人生 阅读(172) | 评论 (0)编辑 收藏

    仅列出标题
    共25页: First 10 11 12 13 14 15 16 17 18 Last 

    导航

    统计

    常用链接

    留言簿(3)

    随笔分类

    随笔档案

    搜索

    最新评论

    阅读排行榜

    评论排行榜