多字节字符集与Unicode字符集
在计算机中字符通常并不是保存为图像,每个字符都是使用一个编码来表示的,而每个字符究竟使用哪个编码代表,要取决于使用哪个字符集(charset)。
多字节字符集:
在最初的时候,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字符集:
Unicode的学名 是"Universal Multiple-Octet Coded Character Set",简称为UCS。UCS可以看作是"Unicode Character Set"的缩写。UCS只是规定如何编码,并没有规定如何传输、保存这个编码。UTF是“UCS Transformation Format”的缩写。
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编码了。
Windows就是使用BOM来标记文本文件的编码方式的。
L是用来标志一个字符(串)为宽字符(串),当你在VS2005以上版本的IDE工作时,可以选择工作于这两种不同的编码方式下,而在Unicode方式下,则要对字符(串)常量前添加L来告诉编译器它是宽字符。MS为我们定义了好几个相关的宏:_T(定义于tchar.h)、_TEXT(同样定义于tchar.h)。
// 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,,wc,wcslen(wc),NULL,,NULL,NULL);
m_char=new char[len+];
WideCharToMultiByte(CP_ACP,,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,,c,strlen(c),NULL,);
m_wchar=new wchar_t[len+];
MultiByteToWideChar(CP_ACP,,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;
多字节字符集与Unicode字符集的更多相关文章
- 字符集研究之多字节字符集和unicode字符集
作者:朱金灿 来源:http://blog.csdn.net/clever101 本文简介计算机中两大字符集:多字节字符集和unicode字符集的出现及关系. 首先我们须要明确的是计算机是怎样找到字符 ...
- ASCII字符集。扩展ASCII字符集。Unicode字符集分别支持多少个字符?
ASCII字符集.扩展ASCII字符集.Unicode字符集分别支持多少个字符? 256个字符和 65536个字符
- 【转】CEF3加载网页---多字节字符集和UNICODE字符集
static char* MBSCToCEF(const char* mbcsStr) { wchar_t* wideStr; char* utf8Str; int charLen; charLen ...
- UNICODE字符集(20140520)
1多字节字符集,如"IT学吧",sizeof内存长度为7,因为前面2个字母各占用一个字节,后面两个汉字各占用2个字节,结尾的\0占用一个字节.strlen即字符串长度的结果为6. ...
- ASCII码与unicode字符集
问题1:为什么需要字符ASCII码.unicode码等等???它们到底有什么作用? 首先要明白一个事实:在计算机中只能用一系列存储着的0和1,当我们把一个字符存放在计算机时,我们是如何表示常用的字符呢 ...
- Unicode字符集,utf8编码,base64编码简单了解
Unicode字符集,utf8编码,base64编码简单了解 Unicode字符集,ASCII,GB2312编码集合等,类似于不同的字典,不同的字符的编码,类似于字典中的字在哪一个页哪一排. 当不同系 ...
- 转: 带你玩转Visual Studio——带你理解多字节编码与Unicode码
上一篇文章带你玩转Visual Studio——带你跳出坑爹的Runtime Library坑帮我们理解了Windows中的各种类型C/C++运行时库及它的来龙去脉,这是C++开发中特别容易误入歧途的 ...
- 带你玩转Visual Studio——带你理解多字节编码与Unicode码
目录(?)[-] 多字节字符与宽字节字符 char与wchar_t string与wstring string 与 wstring的相关转换 字符集Charcater Set与字符编码Encoding ...
- C语言的源程序字符集与执行字符集
我们程序文件的字符集就是我们写出来的.c扩展名的文件的字符集,这里用的是系统默认的 ANSI 字符集,如下图: 上面的字符集我们不关心,我们关心的是 源程序的字符集 和程序的 执行字符集 ,源程序的字 ...
随机推荐
- js高级-变量内存分析
var a = 9, b, c={age:9}, d; b = a; b = 19; console.log(a) console.log(b) d = c; d.age = 22; console ...
- 获取镜像tag
# curl -k https://k8s.gcr.io/v2/fluentd-elasticsearch/tags/list|jq .tags % Total % Received % Xferd ...
- js循环对象,(多层数组)
javaScript遍历对象.数组总结 在日常工作过程中,我们对于javaScript遍历对象.数组的操作是十分的频繁的,今天抽空把经常用到的方法小结一下,方便今后参考使用! javaSc ...
- jq控制select值为某个时选中
$("#selectche_type option").each(function(){//用id ,用class好像不得,不知道为何 alert(2) if($(this).va ...
- pyhton笔记(一):字符编码、变量
一.什么是python? python是一种面向对象.解释型的计算机语言,它的特点是语法简洁.优雅.简单易学. 编译型语言: 写好代码之后把代码编译成二进制文件,运行时运行编译好的二进制文件.比如C. ...
- AI图谱
- Python+Selenium学习--定位一组对象
场景 从上一节的例子中可以看出,webdriver可以很方便的使用find_element方法来定位某个特定的对象,不过有时候我们却需要定位一组对象,这时候就需要使用find_elements方法. ...
- 十个前端UI优秀框架
最近需要一些前端框架,于是在网上整理了一些感觉不错的前端框架,有pc端和移动端,为了方便日后自己先记录下来了... Bootstrap 首先说 Bootstrap,估计你也猜到会先说或者一定会有这个( ...
- chase
chase 英[tʃeɪs] 美[tʃes] vt. 追求; 追捕; 追寻; 镂刻; n. 追捕; 打猎; 猎物(指鸟兽等); 槽; vi. 追逐,追赶; 追寻; 追求(常与after连用); [口语 ...
- Rxjs之创建操作符(Angular环境)
一 of操作符 import { Component, OnInit } from '@angular/core'; import { of } from 'rxjs/observable/of'; ...