最近在读《Windows核心编程》,加上一个批处理程序的需求,渐渐对ANSI跟Unicode字符有些理解了。在这里写个小结。
1、运算
wchar_t strW[100] = L"这是个..."; //这是Unicode
char str[100] = "这是个..."; //这是ANSI
Unicode在C++中的形式多为宽字符(wchar_t)数组,因为wchar_t占用16位内存,符合目前Windows系统用UTF-16对Unicode字符进行编码。
而ANSI中的汉字,都是由两个字符(char)来表示。
程序的监视结果为
2、读
只谈一下从键盘读入,用C++输入输出流的cin,
std::cin >> str;
std::cin >> strW;
会发现第二条语句无法编译通过,因此,用C++输入输出流,只能输入ANSI字符。
3、写
用读写文件流fstream,向文件中输出,
std::ofstream outFile("d:\\test1.txt", std::ios::app | std::ios::out);
outFile << strW;
可以执行,但是查看执行结果是发现,输出完全不对。
看网上有人说读写文件流支持Unicode,出现乱码的原因自己还不知道。因此在这里,建议输出时还是换回ANSI
4、相互转化
4.1 Unicode ----> ANSI
int len_char = 0;
PCSTR pUnid = NULL;
PBOOL pAlter = new BOOL('?');
len_char = WideCharToMultiByte(936, 0, strW, -1, NULL, 0, pUnid, pAlter);
//得到转化后的ANSI字符长度,以便分配空间。
char * strFrom_strW = new char [len_char];
WideCharToMultiByte(936, 0, strW, -1, strFrom_strW, len_char, pUnid, pAlter);
delete pAlter;
这里用到的是Windows函数WideCharToMultiByte,得包含<windows.h>。函数具体用法在《Windows核心编程》26页起,。见附录。第一个参数:UINT uCodePage,即代码页(内码表),我想是因为UTF-16无法表示所有文字(这是句废话,因为有UTF-32),因此通过这个来确定你大体用的是哪个子集,中文简体是932,中文繁体是950,日文是936……
还是用到之前那两个变量
运行结果为:
4.2 ANSI ----> Unicode
int len_char = 0;
len_char = MultiByteToWideChar(936, 0, str, -1, NULL, 0);
//得到转化后Unicode字符长度,以便分配空间
wchar_t * strWFrom_str = new wchar_t [len_char];
MultiByteToWideChar(936, 0, str, -1, strWFrom_str, len_char);
这个函数跟上面函数基本一致。因为是从ANSI到Unicode,只存在单字符/双字符向代码页中的代码转换的问题,因此不存在在该代码页中找不到字符的情况,因此少了两个参数。另外,分配空间的时候注意,此处分配的是宽字符(尤其是malloc)。
运行结果为:
附录:【Unicode与ANSI字符串转换】
http://msdn.microsoft.com/zh-cn/subscriptions/downloads/aa450989.aspx
【Platfrom SDK文档】
http://support.microsoft.com/kb/108450/zh-cn
http://msdn.microsoft.com/zh-cn/subscriptions/downloads/aa450989.aspx