一、关于VC++中的MultiByte和WideChar
VC++的工程如果设定的是“使用Unicode字符集”,程序中的CString是WideChar数组,采用的编码方式是UTF-16。
调用WideCharToMultiByte转换MultiByte数组,CodePage参数为CP_ACP,得到的MultiByte数组为ANSI编码。
UTF-16编码:每个宽字符固定用2个byte。数字、字母、半角符号等原来用ASCII编码的字符,采用原编码加0x00。例如:字符串“aA12”的编码:0x61 00 41 00 31 00 32 00。汉字“版权归属”的编码:0x48 72 43 67 52 5f 5e 5c。
ANSI编码:字符串中的数字、字母、半角符号等原来用ASCII编码的字符占用1个byte,汉字占用2个byte,采用的是GBK编码。例如:字符串:“aA12版权归属”的编码:0xb0 e6 c8 a8 b9 e9 ca f4 61 41 31 32。
UTF-16编码也可以转接转换为UTF-8编码,UTF-8也是MultiByte编码,调用WideCharToMultiByte转换时,CodePage参数为CP_UTF8。
UTF-8编码中,数字、字母、半角符号等原来用ASCII编码的字符仍然占用1个byte,但是汉字占用的字节数就是变长的了,常用的多数是3个byte,也有占4个byte的。例如:字符串“aA12”的编码与ANSI相同,仍然是:0x61 41 31 32 。汉字“版权归属”的编码:0xe7 89 88 e6 9d 83 e5 bd 92 e5 b1 9e,每个汉字占了3个byte。
二、程序示例:
1、CString的宽字符转换为ANSI多字节:
CString str = L"aA12版权归属";
int len = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, NULL, FALSE);
char* buff=new char[len];
WideCharToMultiByte(CP_ACP, str,-1,buff,len,NULL,FALSE);
。。。
delete[] buff;
2、CString的宽字符转换为UTF-8多字节:
CString str = L"aA12版权归属";
int len = WideCharToMultiByte(CP_UTF8, 0, str, -1, NULL, 0, NULL, FALSE);
char* buff=new char[len];
WideCharToMultiByte(CP_UTF8, str,-1,buff,len,NULL,FALSE);
。。。
delete[] buff;
3、从UTF-8编码的文件中读出的文本,转换成ANSI编码:
//读文件内容
CFile file;
file.Open(path,CFile::modeRead);
int len=file.GetLength();
byte* buff=new byte[len];
file.Read(buff,len);
file.Close();
//UTF-8转换为宽字符
int strlen = MultiByteToWideChar(CP_UTF8, 0, (char*)buff, -1, NULL, 0);
wchar_t* wstr = new wchar_t[strlen+1];
MultiByteToWideChar(CP_UTF8, 0, (char*)buff, -1, wstr, strlen);
delete[] buff;
//宽字符转为为ANSI
len = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);
buff=new byte[len+1];
WideCharToMultiByte(CP_ACP, 0, wstr, -1, (char*)buff, len, NULL, NULL);
delete[] wstr;
。。。
delete[] buff;