在计算机中字符一般并非保存为图像,每一个字符都是使用一个编码来表示的,而每一个字符究竟使用哪一个编码表明,要取决于使用哪一个字符集(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;