UNICODE與ANSI的區別


什么是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      )


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM