多字節字符集與Unicode字符集

  在計算機中字符一般並非保存爲圖像,每一個字符都是使用一個編碼來表示的,而每一個字符究竟使用哪一個編碼表明,要取決於使用哪一個字符集(charset)。 linux

多字節字符集:ios

  在最初的時候,Internet上只有一種字符集——ANSI的ASCII字符集,它使用7 bits來表示一個 字符,總共表示128個字符,其中包括了 英文字母、數字、標點符號等經常使用字符。以後,又進行擴展,使用8 bits表示一個字符,能夠表示256個字符,主要在原來的7 bits字符集的基礎上加入了一些特殊符號。後來,因爲各國語言的加入,ASCII已經不能知足信息交流的須要,爲了可以表示其它國家的文字,各國在 ASCII的基礎上制定了本身的字符集,這些從ANSI標準派生的字符集被習慣的統稱爲ANSI字符集,它們正式的名稱應該是MBCS(Multi-Byte Chactacter System,即多字節字符系統)。這些派生字符集的特色是以ASCII 127 bits爲基礎,兼容ASCII 127,他們使用大於128的編碼做爲一個Leading Byte,緊跟在Leading Byte後的第二(甚至第三)個字符與 Leading Byte一塊兒做爲實際的編碼。這樣的字符集有不少,咱們常見的GB-2312就是其中之一。編程

Unicode字符集:windows

  Unicode的學名 是"Universal Multiple-Octet Coded Character Set",簡稱爲UCS。UCS能夠看做是"Unicode Character Set"的縮寫。UCS只是規定如何編碼,並無規定如何傳輸、保存這個編碼。UTF是「UCS Transformation Format」的縮寫。ide

  Unicode字符集有多種編碼形式,它固定使用16 bits(兩個字節、一個字)來表示一個字符,共能夠表示65536個字符。將世界上幾乎全部語言的經常使用字符收錄其中,方便了信息交流。標準的Unicode稱爲UTF-16。後來爲了雙字節的Unicode可以在現存的處理單字節的系統上正確傳輸,出現了UTF-8(注意UTF-8是編碼,它屬於Unicode字符集),使用相似MBCS的方式對Unicode進行編碼。UTF-8以字節爲編碼單元,沒有字節序的問題。UTF-16以兩個字節爲編碼單元。函數

  UTF-16包括三種:UTF-16,UTF-16BE(Big Endian),UTF-16LE(Little Endian),UTF-16須要經過在文件開頭以名爲BOM(Byte Order Mark)的字符來代表文件是Big Endian仍是Little Endian。Unicode規範中推薦的標記字節順序的方法是BOM(Byte Order Mark)。在UCS編碼中有一個叫作"ZERO WIDTH NO-BREAK SPACE"的字符,它的編碼是FEFF。而FFFE在UCS中是不存在的字符,因此不該該出如今實際傳輸中。UCS規範建議咱們在傳輸字節流前,先傳輸字符"ZERO WIDTH NO-BREAK SPACE"。這樣若是接收者收到FEFF,就代表這個字節流是Big-Endian的;若是收到FFFE,就代表這個字節流是Little-Endian的。所以字符"ZERO WIDTH NO-BREAK SPACE"又被稱做BOM。編碼

  UTF-8不須要BOM來代表字節順序,但能夠用BOM來代表編碼方式。字符"ZERO WIDTH NO-BREAK SPACE"的UTF-8編碼是EF BB BF(讀者能夠用咱們前面介紹的編碼方法驗證一下)。因此若是接收者收到以EF BB BF開頭的字節流,就知道這是UTF-8編碼了。spa

  Windows就是使用BOM來標記文本文件的編碼方式的。code

  L是用來標誌一個字符(串)爲寬字符(串),當你在VS2005以上版本的IDE工做時,能夠選擇工做於這兩種不一樣的編碼方式下,而在Unicode方式下,則要對字符(串)常量前添加L來告訴編譯器它是寬字符。MS爲咱們定義了好幾個相關的宏:_T(定義於tchar.h)、_TEXT(一樣定義於tchar.h)。orm

   TEXt():若是定義了Unicode,標識字符爲Unicode;不然,爲ANSI字符集。在VS2010使用Unicode字符集下:
//    MessageBox("Test");  //錯誤

//    MessageBox(_T("Test"));
//    MessageBox(TEXT("Test"));
      MessageBox(_TEXT("Test"));

  

  對於爲何使用Unicode?(如下引自《windows核心編程》)
  開發應用程序的時候,強烈建議你使用Unicode字符和字符串,理由以下:

  • Unicode使程序的本地化變得更容易;
  • 使用Unicode,只需發佈一個二進制(.exe或DLL)文件,便可支持全部語言;
  • Unicode代碼執行速度更快,佔用內存更少,提高了應用程序的效率。自從Windows2K開始,Win的系統內核開始徹底支持並徹底應用Unicode編寫,全部ANSI字符在進入底層前,都會被相應的API轉換成Unicode。因此,若是你一開始就使用Unicode,則能夠減小轉換的用時和RAM開銷。
  • 使用Unicode,你的應用程序能輕鬆調用全部不反對使用(nondeprecated)的Windows函數,由於一些Windows函數提供了只能處理Unicode字符和字符串的版本;
  • 使用Unicode,你的代碼很容易與COM集成(後者要求使用Unicode字符和字符串);
  • 使用Unicode,你的代碼很容易與.NET Framework集成(後者要要求使用Unicode字符和字符串);
  • 使用Unicode,能保證你的代碼可以輕鬆操縱你本身的資源(其中的字符串老是Unicode的);
  • 世界上大多數程序用的字符集都是Unicode,由於Unicode有利於程序國際化和標準化;

  

  wchar_t與char類型間的轉換:

#include<iostream>  
#include<Windows.h>
using namespace std;  
class CUser  
{  
public:  
    CUser();  
    virtual ~CUser();  
    char* WcharToChar(wchar_t* wc);//寬字節轉單字節   
    wchar_t* CharToWchar(char* c); //單字節轉寬字節   
    void Release();//釋放資源   
private:  
    char* m_char;  
    wchar_t* m_wchar;  
};  
/////////////////////////////////////////////////////////////////////////////////////   
/*字符類型        wchar_t     char 
/*獲取字符長度    wcslen()    strlen() 
/*鏈接兩個字符串  wcscat()    strcpy() 
/*複製字符串      wcscpy()    strcpy() 
/*比較兩個字符串  wcscmp()    strcmp() 
/*具體參數詳見www.linuxidc.com*/  
////////////////////////////////////////////////////////////////////////////////////   
CUser::CUser():m_char(NULL),m_wchar(NULL)  
{  
}  
CUser::~CUser()  
{  
    Release();  
}  

//寬字節轉單字節   
char* CUser::WcharToChar(wchar_t* wc)  
{  
    Release();  
    int len= WideCharToMultiByte(CP_ACP,0,wc,wcslen(wc),NULL,0,NULL,NULL);  
    m_char=new char[len+1];  
    WideCharToMultiByte(CP_ACP,0,wc,wcslen(wc),m_char,len,NULL,NULL);  
    m_char[len]='\0';  
    return m_char;  
}  

//單字節轉寬字節   
wchar_t* CUser::CharToWchar(char* c)  
{  
    Release();  
    int len = MultiByteToWideChar(CP_ACP,0,c,strlen(c),NULL,0);  
    m_wchar=new wchar_t[len+1];  
    MultiByteToWideChar(CP_ACP,0,c,strlen(c),m_wchar,len);  
    m_wchar[len]='\0';  
    return m_wchar;  
}  

//釋放資源   
void CUser::Release()  
{  
    if(m_char)  
    {  
        delete m_char;  
        m_char=NULL;  
    }  
    if(m_wchar)  
    {  
        delete m_wchar;  
        m_wchar=NULL;  
    }  
} 

使用以下:

WCHAR* wc;  
CUser u;  
char* c=u.WcharToChar(wc);  
cout<<c<<endl; 
相關文章
相關標籤/搜索