UNICODE與ANSI的區別

來源:互聯網
上載者:User

什麼是ANSI,什麼又是UNICODE呢?其實這是兩種不同的編碼方式標準,ANSI中的字元採用 8bit,而UNICODE中的字元採用16bit。(對於字元來說ANSI以單位元組存放英文字元,以雙位元組存放中文等字元,而Unicode下,英文和 中文的字元都以雙位元組存放)Unicode碼也是一種國際標準編碼,採用二個位元組編碼,與ANSI碼不相容。目前,在網路、Windows系統和很多大型 軟體中得到應用。8bit的ANSI編碼只能表示256種字元,表示26個英文字母是綽綽有餘的,但是表示漢字,韓國語等有著成千上萬個字元的非西方字元 肯定就不夠了,正是如此才引入了UNICODE標準。   
     在軟體開發中,特別是使用C語言的一些有關字串處理的函數,ANSI和UNICODE是區分是用的,那麼ANSI類型的字元和UNICODE類型的字元如何定義,如何使用呢?ANSI和UNICODE又如何轉換呢?   
   一.定義部分:  
   ANSI:char    str[1024]; 可用字串處理函數:strcpy( ),    strcat( ),   strlen( )等等。
UNICODE:wchar_t    str[1024];可用字串處理函數   
二.可用函數: 
   ANSI:即char,可用字串處理函數:strcat(    ),strcpy(    ),    strlen(    )等以str打頭的函數。   
   UNICODE:即wchar_t 可用字串處理函數:wcscat(),wcscpy(),wcslen()等以wcs打頭的函數。   
   三.系統支援  
      Windows    98    :只支援ANSI。   
      Windows    2k    :既支援ANSI又支援UNICODE。   
      Windows    CE    :只支援UNICODE。   
      說明   
      1 在COM裡面只支援UNICODE。   
      2.Windows   2000整個OS系統都是基於UNICODE的,為此在windows 2000 下使用ANSI是需要付出代價的,雖然在編碼上不用任何的轉換,但是這種轉化是隱藏的,是佔用系統資源的(CPU,記憶體)。   
      3 在Windows 98下必須使用UNICODE,則需要自己手動的編碼切換。   
    四.如何區分:   
    在我們軟體開發中往往需要即支援ANSI又支援UNICODE,不可能在要求類型轉換的時候,重新改變字串的類型,和使用於字串上的操作函數。為此, 標準C運行期庫和Windows 提供了宏定義的方式。   
    在C語言裡面提供了 _UNICODE宏(有底線),在Windows裡面提供了UNICODE宏(無底線),只要定了_UNICODE宏和UNICODE宏,系統就會自動切換到UNICODE版本,否則,系統按照ANSI的方式進行編譯和運行。   
    只定義了宏並不能實現自動的轉換,他還需要一系列的字元定義支援。   
   1. TCHAR   
   如果定義了UNICODE宏則TCHAR被定義為wchar_t。   
    typedef    wchar_t    TCHAR;   
    否則TCHAR被定義為char   
    typedef    char   TCHAR;   
   2.LPTSTR   
如果定義了UNICODE宏則LPTSTR被定義為LPWSTR。(以前一直不知道LPWSTR是什麼東東,終於明白了)   
   typedef    LPTSTR   LPWSTR;   
   否則TCHAR被定義為char   
   typedef    LPTSTR   LPSTR;  
補充一下:
UTF-8是可以用於真正的串流的,Unicode是一種編碼方案   
    我的理解是UTF-8是Unicode的一種具體實現。類似的實現還有UTF-16等等。


ANSI/Unicode字元和字串 
TChar.h是String.h的修改,用於建立ANSI/Unicode通用字串。

Unicode字串的每個字元都是16位的。

Win9x只支援ANSI;Win2000/XP/2003支援ANSI/Unicode;WinCE只支援Unicode
       附:有部分Unicode函數也可以在Win9X中使用,但可能會出現意想不到錯誤。

wchar_t是Unicode字元的資料類型。

所有的Unicode函數均以wcs開頭,ANSI函數均以str開頭;ANSI C規定C運行期庫支援ANSI和Unicode
                                 ANSI                                                                              Unicode
       char   *strcat(char   *,   const   char   *)                           wchar_t   *wcscat(wchar_t   *,   const   wchar_t   *) 
       char   *strchr(const   char * , int)                                   wchar_t    *wcschr(const   wchar_t   * , int) 
       int   strcmp(const   char   *,    const   char   *)                int    wcscmp(const   wchar_t   *, const   wchar_t *)
       char *strcpy(char   *,   const   char   *)                           wchar_t   *wcscpy(wchar_t    *,   const   wchar_t    *)
       size_t   strlen(const   char   *)                                        wchar_t    wcslen(const   wchar_t   *)

L" wash " : 用於將ANSI字串轉換為Unicode字串;
        _TEXT(" wash ")根據是否定義Unicode或_Unicode進行轉換。
       附:_Unicode用於C運行庫;Unicode用於Windows標頭檔。

ANSI/Unicode通用資料類型
                        Both(ANSI/Unicode)                    ANSI                       Unicode
                               LPCTSTR                                 LPCSTR                   LPCWSTR
                               LPTSTR                                    LPSTR                      LPWSTR
                               PCTSTR                                   PCSTR                      PCWSTR
                               PTSTR                                      PSTR                         PWSTR
                               TBYTE(TCHAR)                      CHAR                         WCHAR

在設計dll時最好提供ANSI和Unicode函數,ANSI函數只用於分配記憶體,將字元轉換為Unicode字元,然後調用Unicode函數。

最好使用作業系統函數,少使用或不實用C運行期函數
        eg:作業系統字串函數(shlWApi.h)
                StrCat(), StrChr(), StrCmp(), StrCpy()等
                注意它們區分大小寫,也區分ANSI和Unicode版本
        附:ANSI版函數在原函數後加大寫字母A
                Unicode函數在原函數後加大寫字母W

成為符合ANSI和Unicode的函數
        ? 將文本串視為字元數組,而不是c h a r s數組或位元組數組。
        ? 將通用資料類型(如T C H A R和P T S T R)用於文本字元和字串。
        ? 將顯式資料類型(如B Y T E和P B Y T E)用於位元組、位元組指標和資料緩衝。
        ? 將T E X T宏用於原義字元和字串。
        ? 修改字串運算問題 。
          如:sizeof(szBuffer) -> sizeof(szBuffer) / sizeof(TCHAR)
                  malloc(charNum) -> malloc(charNum * sizeof(TCHAR))   

對Unicode字元操作的函數還有:(也有ANSI和Unicode版本)
       lstrcat() , lstrcmp() / lstrcmpi()[ 它們在內部調用CompareString() ], lstrcpy(), lstrlen()
       這些是作為宏實現的。

          C運行期函數                                       windows函數
                  tolower()                                  PTSTR   CharLower(PTSTR   pszString)
                  toupper()                                 PTSTR   CharUpper(PTSTR   pszString)
                  isalpha()                                  BOOL   IsCharAlpha(TCHAR   ch)
                                                                   BOOL   ISCharAlphaNumeric(TCHAR   ch)
                  islower()                                  BOOL   IsCharLower(TCHAR   ch)
                  isupper()                                 BOOL   IsCharUpper(TCHAR   ch)
                  print()                                       wsprintf()
       轉換Buffer:DWORD   CharLowerBuffer(PTSTR   pszString , DWORD cchString)
                              DWORD CharUpperBuffer(PTSTR   pszString , DWORD   cchString)
       也可轉換單個字元,如:TCHAR   cLowerCaseChar = CharLower((PTSTR)szString[0])

確定字元是ANSI或Unicode
        BOOL   IsTextUnicode(
                     const   VOID   * pBuffer,   //input   buffer   to be   examined
                     int   cb,                               //size of input   buffer
                     LPINT   lpi                         //options
        )
       附:此函數在Win9x系統中,沒有實現代碼,始終返回FALSE

Unicode與ANSI之間的轉換
        char   szA[40];
        wchar   szW[40];
        // Normal   sprintf : all   string   are   ANSI
        sprintf( szA , " %s " , " ANSI   str ");
        // Convert   Unicode   string   to ANSI
        sprintf(   szA,   " %S " ,   L" Unicode   str ");
        // Normal   swprintf : all string are unicode
        swprinf( szW , "%s" , L" Unicode   str ");
        // Convert   ANSI   String to Unicode
        swprinf( szW, L"%S" , "ANSI str");

        int   MultiByteToWideChar(
              UINT   uCodePage,                   //code page,   0
              DWORD   dwFlags,                   //character-type   options,   0
              PCSTR   pMultiByte,                  //source   string   Addr
              int   cchMultiByte,                       //source   string   byte length
              PWSTR   pWideCharStr,          //Dest string   Addr
              int   cchWideChar                      //Dest   string char   Nums
         )
        u C o d e P a g e參數用於標識一個與多位元組字串相關的字碼頁號。d w F l a g s參數用於設定另一個控制項,它可以用重音符號之類的區分標記來影響字元。這些標誌通常並不使用,在d w F l a g s參數中傳遞0。p M u l t i B y t e S t r參數用於設定要轉換的字串, c c h M u l t i B y t e參數用於指明該字串的長度(按位元組計算)。如果為c c h M u l t i B y t e參數傳遞- 1,那麼該函數用於確定源字串的長度。轉換後產生的U n i c o d e版本字串將被寫入記憶體中的緩衝,其地址由p Wi d e C h a r S t r參數指定。必須在c c h Wi d e C h a r參數中設定該緩衝的最大值(以字元為計量單位)。如果調用M u l t i B y t e To Wi d e C h a r,給c c h Wi d e C h a r參數傳遞0,那麼該參數將不執行字串的轉換,而是返回為使轉換取得成功所需要的緩衝的值。

     可以通過下列步驟將多位元組字串轉換成U n i c o d e等價字串:
     1) 調用M u l t i B y t e To Wi d e C h a r函數,為p Wi d e C h a r S t r參數傳遞N U L L,為c c h Wi d e C h a r參數傳遞0。
     2) 分配足夠的記憶體塊,用於存放轉換後的U n i c o d e字串。該記憶體塊的大小由前面對M u l t B y t e To Wi d e C h a r的調用返回。
     3) 再次調用M u l t i B y t e To Wi d e C h a r,這次將緩衝的地址作為p Wi d e C h a r S t r參數來傳遞,並傳遞第一次調用M u l t i B y t e To Wi d e C h a r時返回的緩衝大小,作為c c h Wi d e c h a r參數。
     4) 使用轉換後的字串。
     5) 釋放U n i c o d e字串佔用的記憶體塊。

    int WideCharToMultiByte(
          UINT CodePage,                        // code page
          DWORD dwFlags,                      // performance and mapping flags
          LPCWSTR lpWideCharStr,      // wide-character string
          int cchWideChar,                       // number of chars in string
          LPSTR lpMultiByteStr,               // buffer for new string
          int cbMultiByte,                           // size of buffer
          LPCSTR lpDefaultChar,            // default for unmappable chars
          LPBOOL lpUsedDefaultChar   // set when default char used
     )

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.