在計算機中字符一般並非保存爲圖像,每一個字符都是使用一個編碼來表示的,而每一個字符究竟使用哪一個編碼表明,要取決於使用哪一個字符集(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
// MessageBox("Test"); //錯誤 // MessageBox(_T("Test")); // MessageBox(TEXT("Test")); MessageBox(_TEXT("Test"));
對於爲何使用Unicode?(如下引自《windows核心編程》)
開發應用程序的時候,強烈建議你使用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;