Win32中的字符编码与字符类型

PS:阿婆主水平有限,以下言论(多为百度得来)可能有错,请大家辩证的看!!!!不要拍砖!


文本操作是编程时的最基本内容,但是,如果程序需要显示中文信息,不少人被什么宽字符,ANSI编码,Unicode编码弄的头晕脑胀!(还是身在美帝好呀!!人家就26个字母呀!!)

众所周知!标准ASCII码是7位的(什么?你一直以为是8位的?),而扩展ASCII码,也就是我们所熟知的ANSI字符集是八位的!在C/C++中,所有人都知道一个char类型占一个字节,那么发展中国家的程序员要如何表示汉字的呢?起初,程序员们提出了一个双字节字符集方案(DBCS),但是这个方案之中并不是所有字符都是两个字节,而是有的一个字节(那些ASCII码),其他的通过一个前导字节和一个尾随字节表示(这些字符用char表示),由于,这个方案十分脑残,因此,C语言开始支持宽字节标准(ANSI C),用wchar来,表示支持多字节字符集!

下面我们来看一下如何使用宽字符集:

#include<stdio.h>
#include<stdlib.h>
#include<locale.h>
int main(int argc,char **argv)
{
	_wsetlocale(LC_ALL,L"chs");//指定编码
	wprintf(L"%ls",L"abcd你好\n");//言下之意就是让你在使用wprintf之前必须调用 _wsetlocale 函数。
	wprintf(L"%lc",L'大天才');
	wprintf(L"%lc\n",L'a');
	return 0;
}
在由于C语言是基于ANSI编码方式的,因此我们为了正确输出宽字符,我需要用local函数把语言设定为中文。


也许你会说,根本不需要如此麻烦,你的printf也能正确输出!!(我也是这么觉得的!!)这好像是因为,Windows下你的cmd和VS同样使用GB2312的编码方式,所以你成功了,但是,如果你进行你代码移植(比如到linux下),你的代码可能会失败!


我们知道C语言是基于ANSI的编码方式,而Windows编程则提倡使用UNICODE,下面我们谈谈他们的区别!


以下来自百度百科:

不同的国家和地区制定了不同的标准,由此产生了 GB2312、GBK、Big5、Shift_JIS 等各自的编码标准。这些使用 1 至 4 个字节来代表一个字符的各种汉字延伸编码方式,称为 ANSI 编码。在简体中文Windows操作系统中,ANSI 编码代表 GBK 编码;在日文Windows操作系统中,ANSI 编码代表 Shift_JIS 编码。 不同 ANSI 编码之间互不兼容,当信息在国际间交流时,无法将属于两种语言的文字,存储在同一段 ANSI 编码的文本中。 当然对于ANSI编码而言,0x00~0x7F之间的字符,依旧是1个字节代表1个字符。 

由于ANSI编码存在地域之间的编码,因此,我们提倡使用UNICODE编码方式。WINDOWS自从某个版本以后,内部函数统统使用UTF16的编码方式,同时,为了向后兼容,WINDOWS为许多函数提供了,两个编码版本的实现(比如,CreateWindowA和CreateWindowW,但是有意思的是,ANSI其实并没有创建一个窗口,他所做的是将字符串从ANSI编码转换为UNICODE编码,然后调用CreateWindow的UNICODE版本!!)。程序员编程时,通过定义关键字UNICODE我们基本上感觉不到这些差异。但是,据《WINDOWS核心编程》所说,后者的效率更高!

在WIN32编程中,我们一般认为,WCHAR指定的就是UTF16编码的宽字符,而CHAR指的就是ANSI编码(两者分别是wchar_t,和char的类型定义,微软为了让别人看不懂他们的代码就爱搞这些!!!)。同时,微软建议我们使用TCHAR来定义字符,用TEXT宏来定义字符串字面值


ANSI字符串和UNICODE字符串之间的转换。

我们用MultiByteToWideChar实现ANSI(多字节)到UNICODE(宽字节)的转换,

<span style="color:#333333;">int MultiByteToWideChar(
		UINT uCodePage,//与多字节字符串关联的一个代码页值,使用<span style="font-family: Arial, Helvetica, sans-serif;">CP_ACP</span><span style="font-family: Arial, Helvetica, sans-serif;">当前计算机操作系统的Windows代码页</span>
		DWORD dwFlags,//额外的控制变量,一般为0
		PCSTR pMultiByteStr,//多字节字符串
		int cbMultiByte,//多字节字符串的,字节长度,若为-1,则自动判断长度
		PWSTR pWideChatStr,//转换结果,为NULL返回有几个字符
		int cchWideChar//宽字节字符数
		)

一般我们遵循下面顺序转换:

#include<Windows.h>
int main(int argc,char **argv)
{
	PSTR pMultiCharStr="今天是星期天";
	PWSTR pWideCharStr; 
	int nLenOfWideCharStr=MultiByteToWideChar(CP_ACP,0,pMultiCharStr,-1,NULL,0);//计算多字节字符串中有几个字符
	pWideCharStr=(PWSTR)HeapAlloc(GetProcessHeap(),0,nLenOfWideCharStr*sizeof(WCHAR));//分配宽字节内存空间间
	MultiByteToWideChar(CP_ACP,0,pMultiCharStr,-1,pWideCharStr,nLenOfWideCharStr);
	MessageBox(NULL,pWideCharStr,L"多字节转换为宽字节",MB_OK);
	HeapFree(GetProcessHeap(),0,pWideCharStr);
	return 0;
}
类似的从UNICODE转换到ANSI使用函数WideCharToMultiByte
int MultiByteToWideChar(
<span style="white-space:pre">	</span>UINT uCodePage,//与多字节字符串关联的一个代码页值,使用CP_ACP,当前计算机操作系统的Windows代码页
<span style="white-space:pre">	</span>DWORD dwFlags,//额外的控制变量,一般为0
<span style="white-space:pre">	</span>PCWSTR pWideCharStr,//宽字节字符串
<span style="white-space:pre">	</span>int cchWideChar,//宽字节字符串的,字符数,若为-1,则自动判断长度
<span style="white-space:pre">	</span>PSTR pMultiByteStr,//转换结果,为NULL返回字节数
<span style="white-space:pre">	</span>int cbMultiByte,//多字节字符串字节数
<span style="white-space:pre">	</span>PCSTR pDefaultChar,//不可转换的字符使用什么填充,NULL
<span style="white-space:pre">	</span>PBOOL flag//是否有不可转化的字符,NULL
<span style="white-space:pre">	</span>)

以上内容来自《Windows核心编程》第二章!

这一章中还介绍了,使用函数IsTextUnicode判断文本的编码类型是否是Unicode,两个字符串比较函数CompareString和CompareStringOrdinal,以及所谓的安全字符串函数内容!










  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值