文章目录
ANSI多字节字符集
最初,Internet上只有一种字符集——ANSI(American National Standard Institute)的ASCII(American Standard Code for Information Interchange)字符集。
后来,不同的国家和地区制定了不同的标准,由此产生了 GB2312、GBK、GB18030、Big5、Shift_JIS 等各自的编码标准。这些使用多个字节来代表一个字符的各种汉字延伸编码方式,称为 ANSI 编码。从ANSI标准派生的字符集被习惯的统称为ANSI字符集,它们正式的名称应该是MBCS(Multi-Byte Chactacter System,即多字节字符系统)。
由字节数据的最高位判断:
- 最高位为0,代表是单字节,按照ASCII表进行编码
ASCII编码是用一个字节(8bit)表示的字符编码,其中只用到了7位,表示127个字符。 - 最高位为1,代表是本地化扩展字符,需要将相邻的两个字节组成一个整体,来进行码值求取,得到的码值对应的本地化字符集中可以得到相应的字符是什么。
- 简体中文系统下,ANSI编码代表GB2312编码(GBK是GB2312的扩展,兼容GB2312)
- 繁体中文系统下,ANSI编码代表BIG5编码
- 日文系统下,ANSI编码代表JIS编码
不同ANSI编码之间互不兼容,当信息在国际间交流时,无法将属于两种语言的文字,存储在同一段ANSI编码的文本中。需要将不同的ANSI编码都转换成UTF-8编码,进而存储。
Unicode字符集
Unicode即Universal Multiple-Octet Coded Character Set,通用多八位编码字符集。
国际组织制定的可以容纳世界上所有文字和字符的编码方案,分为多个平面,一般常用0号平面也叫基本多文种平面(Basic Multilingual Plane)即Ox0000-OxFFFF
来表示一个字符(对于英文浪费了一个字节)。
- UTF-8(最主流的编码方式)
UTF-8是Unicode的实现方式之一,是一种针对Unicode的可变长度字符编码,使用1-4个字节进行编码。
Unicode编号范围 | 码位数 | UTF-8使用字节数 | UTF-16使用字节数 | 二进制最大有效位数 | 转换为字节编码 |
---|---|---|---|---|---|
00-7F | 128 | 1 | 2 | 7 | 0xxxxxxx |
80-7FF | 1920 | 2 | 2 | 11 | 110xxxxx 10xxxxxx |
800-FFFF | 63488 | 3 | 2 | 16 | 1110xxxx 10xxxxxx 10xxxxxx |
100000-10FFFF | 1048576 | 4 | 4 | 21 | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx |
- UTF-16
可变长度字符编码,将字符编码成2字节或者4字节 - UTF-32
固定长度的编码,始终占用4字节。
Windows平台的字符转换
头文件<tchar.h>
作用就是为了进行ASCII码和UNICODE(wide-character)码的头文件(该头文件由微软提供)
L指令
字符串前面加L表示该字符串是Unicode字符串,可以将ANSI字符串转换为Unicode字符串,就是每个字符占2个字节。
strlen("abc") = 3;
strlen(L"abc") = 6;
_T()宏
_T(“”)是一个宏定义在tchar.h下。
_T()或者TEXT()宏,可以把引号括起来的字符串,根据环境选择合适的编码方式。
- 如果定义的是Unicode,那么_T(“abc”)就相当于L"abc",也就是宽字符;
- 如果是多字节编码,那么英文采用单字节,汉字采用双字节;
- 在Unicode环境下,要求LPCWSTR的地方不可以给一个char*,而在多字节编码下可以。
比如
wchar_t Str[] = L"Hello World!";
是双字节存储字符串,_T是与之适配的宏。
当有#ifdef _UNICODE
的时候,_T()就是L;
当没有#ifdef _UNICODE
的时候,_T()就是ANSI的。
MFC中CString
CString实际是CStringT,也就是模板类
在Unicode环境下,实际是CStringW
在多字符集环境下,实际是CStringA
GB2312与UTF-8的转换
char* U2G(const char* utf8)
{
int len = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0);
wchar_t* wstr = new wchar_t[len + 1];
memset(wstr, 0, len + 1);
MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wstr, len);
len = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);
char* str = new char[len + 1];
memset(str, 0, len + 1);
WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, len, NULL, NULL);
if (wstr) delete[] wstr;
return str;
}
char* G2U(const char* gb2312)
{
int len = MultiByteToWideChar(CP_ACP, 0, gb2312, -1, NULL, 0);
wchar_t* wstr = new wchar_t[len + 1];
memset(wstr, 0, len + 1);
MultiByteToWideChar(CP_ACP, 0, gb2312, -1, wstr, len);
len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);
char* str = new char[len + 1];
memset(str, 0, len + 1);
WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, NULL, NULL);
if (wstr) delete[] wstr;
return str;
}
标签:编码,字节,字符,字符集,len,ANSI,wstr,NULL
From: https://blog.csdn.net/qq_39281631/article/details/141098322