字符集
标准ASCII字符集
•ASCII: 美国信息交换标准代码,包含英文,符号等
•标准ASCII 使用1个字节存储字符,首位是0,总共使用128个字符
GBK :汉字内码扩展规范,国标
•汉字编码字符集,包含了2万多个汉字等字符,GBK中一个中文字符编码成两个字节的形式存储
•注意:GBK 是兼容了ASCII字符集的
存储后如何解码,计算机底层如何区分
•国标规定:汉字的第一个字节的第一位必须是1
比如:
ex: 益a达
xxxxxxxx
益 a 达
1xxxxxxx xxxxxxxx 1xxxxxxx xxxxxxxx
Unicode 字符集(统一码,也叫万国码)
•Unicode 是国际组织制定的,可以兼容世界上所有
•Unicode只是一个字符集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。
提供了几种编码方案:
UTF-32 4个字节表示一个字符,占存储空间,通信效率变低
UTF-8 采取可变长编码方案,共分四个长度区:1个字节,2个字节,3个字节,4个字节UTF-16 是一种可变宽度编码方案,每个字符至少使用2个字节,最大使用4个字节。这 使UTF-16可以用Unicode表示任何字符,同时为最常用的字符使用最小的。有 字节序
UCS-2 UCS-2是一种固定宽度的编码,每个字符使用两个字节,已过时,此后已替换为 UTF-16
总结:
• ASCII 字符集: 只有英文、数字、符合等,占 1 个字节• GBK 字符集: 汉字占 2 个字节, 英文、 数字 占 1 个字节• Unicode 字符集 (UTF-8 编码方案): 汉字占 3 个字节, 英文、数字占 1 个 字节注意1 :字符编码时使用的字符集,和解码时使用的字符集必须一致,否则会出现乱码注意2:英文和数字一般不会出现乱码,因为很多字符集都兼容ASCII编码
Visual Studio:
多字节字符集 通常指的是ANSI(GB2312、Shift-jis、jis、ecu_jp)
Unicode字符集 通常指的是 UTF-8, UTF-16,UTF-32等
(1)每种ANSI字符集只规定自己国家或地区使用的语言所需的'字符';比如简体中文编码标准GB-2312的字符集中就不会包含韩国人的文字。
(2) ANSI字符集的空间都比ASCII要大很多,一个字节已经不够,绝大多数ANSI编码标准都使用多个字节来表示一个字符。
(3) ANSI编码标准一般都会兼容ASCII码
类型转换
类型的理解
char 8bit
wchar_t 16bit
string 内部使用chat类型
由于数据结构比较复杂(使用CStringData),所以在使用的时候就出现了很多的问题,出现这个问题的原因就是CString为了方便某些应用,提供了一些operations,这些operation可以直接返回内存块中的字符串的地址值,用户可以通过对这个地址值指向的地址进行修改,但是,修改后又没有调用相应的operations1使CStringData中的值来保持一致。
比如,用户可以首先通过operations得到字符串地址,然后将一些新的字符增加到这个字符串中,使得字符串的长度增加,但是,由于是直接通过指针修改的,所以描述该字符串长度的CStringData中的nDataLength却还是原来的长度,因此当通过GetLength获取字符串长度时,返回的必然是不正确的。
CString( );
例:CString csStr;
CString( const CString& stringSrc );
例:CString csStr("ABCDEF中文123456");
CString csStr2(csStr);
CString( TCHAR ch, int nRepeat = 1 );
例: CString csStr('a',5);//csStr="aaaaa“
CString( LPCTSTR lpch, int nLength );
例:CString csStr("abcdef",3);//csStr="abc“
CString( LPCSTR lpsz );
例:CString csStr("abcdef");//csStr="abcdef“
printf("%d",csStr.GetLength())
ANSI 转 Unicode
int MultiByteToWideChar(
UINT uCodePage, //CP_ACP
DWORD dwFlags, //一般为 0
PCSTR pMultiByteStr, //要转换的ANSI字符串
int cbMultiByte, //指定字符串的字节数,传-1,则自动判断
PWSTR pWideCharStr, //Unicode宽字符缓冲区,可为NULL
int cchWideChar //指定缓冲区字符数,如果传入0,则返回需要 宽字符数(包 括'\0'
);
一般调用两次,完成转换。第一次获取结果需要的字符数,第二次完成转换
Unicode 转 ANSI
int WideCharToMultiByte(
UINT uCodePage, //CP_ACP
DWORD dwFlags, //一般为 0
PCSTR pWideCharStr, //要转换的Unicode字符串
int cchWideChar, //指定字符串的长度(字符数),传-1,则自动判断
PWSTR pMultiByteStr, //ANSI字符串缓冲区,可为NULL
int cbMultiByte, //指定缓冲区字节数,如果传入0,则返回需要的 字节数(包括‘\0’)
PCSTR pDefaultChar, //遇到无法转换时,使用默认字符来代替。如果为NUL,使用系统默认
字符,通常为一个问号
PBOOL pfUsedDefaultChar //返回值。如果全部成功返回FALSE,否则返回TRUE
);
一般调用两次,完成转换。第一次获取结果需要的字符数,第二次完成转换
UTF8ToUnicode
wstring UTF8ToUnicode(const string& str)
{
int len = 0;
len = str.length();
int unicodeLen = ::MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, NULL, 0);
wchar_t * pUnicode;
pUnicode = new wchar_t[unicodeLen + 1];
memset(pUnicode, 0, (unicodeLen + 1) * sizeof(wchar_t));
::MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, (LPWSTR)pUnicode, unicodeLen);
wstring rt;
rt = (wchar_t*)pUnicode;
delete pUnicode;
return rt;
}
ANSIToUnicode
wstring ANSIToUnicode(const string& str)
{
int len = 0;
len = str.length();
int unicodeLen = ::MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, NULL, 0);
wchar_t * pUnicode;
pUnicode = new wchar_t[unicodeLen + 1];
memset(pUnicode, 0, (unicodeLen + 1) * sizeof(wchar_t));
::MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, (LPWSTR)pUnicode, unicodeLen);
wstring rt;
rt = (wchar_t*)pUnicode;
delete pUnicode;
return rt;
}
UnicodeToANSI
string UnicodeToANSI(const wstring& str)
{
char* pElementText;
int iTextLen;
// wide char to multi char
iTextLen = WideCharToMultiByte(CP_ACP, 0, str.c_str(), -1, NULL, 0, NULL, NULL);
pElementText = new char[iTextLen + 1];
memset((void*)pElementText, 0, sizeof(char) * (iTextLen + 1));
::WideCharToMultiByte(CP_ACP, 0, str.c_str(), -1, pElementText, iTextLen, NULL, NULL);
string strText;
strText = pElementText;
delete[] pElementText;
return strText;
}