宽字符,Ansic和Unicode

电脑发展的初期,只是在美国等英文国家使用,英文只有26个字母和其它字符,一个字节最多可以表示256个字符,如字母“A”用0x41(二进制01000001)表示,字母“a”用0x61(二进制01100001)表示。为了使各家电脑公司生产的电脑统一,美国搞了个国家标准ANSI,一直沿用至今,我们今天用的电脑普通情况下使用的都ANSI编码。

ANSI编码,每个字符占一个字节,但最多只能表示256个字符。
汉字等东亚语言字符怎么办呢?于是采用两个字节共同表示一个汉字的方法。二个字节理论上可以表示65535个字符。
因为ANSI标准是用一个字节的7个位表示一个普通字符,最高位为0(如字母“A”的二进制01000001),所以表示汉字就采用最高位为1来表示。如“中”字就是用0xD6、0xD0表示(二进制11010110、11010000)。
程序员判断一个字符是否为汉字,就是通过最高位是否为1来判断的。

但是,中国大陆的汉字表示方法叫GB码(中国国家标准,如GB2312),中国台湾、香港的汉字表示方法叫BIG5码(大五码,台湾一家民营公司提出),还有韩、日等字符,还是造成了计算机文字表示的不统一。
所以,在W98时代,电脑上网、收发邮件等经常出现乱码的现象(就是文字标准不统一造成的)

ANSI编码字符,叫多字节字符

UNICODE编码,每个字符占二个字节。也叫万国码(一种国际标准字符集,为世界上绝大多数已知的字符集定义了唯一的16位数值)

UNICODE编码的数字、字母等,保留原ANSI的8位编码,后面加上八个二进制0。
中国国家标准的UNICODE编码汉字,叫GB18030(与UNICODE相同,2002年开始执行),有27533个汉字。

UNICODE编码字符,叫宽字节字符

从Windows 2000开始,使用UNICODE编码,但为了保持兼容,默认的还是ANSI编码。

上面各位提出了两个函数:
WideCharToMultiByte()  //宽字符转多字节字符 
MultiByteToWideChar()  //多字节字符转宽字符 
就是用于两种字符转换的。

那么程序员如何处理这两种编码方式呢?

你可以使用默认的ANSI编码,也可以使用UNICODE编码
比如在VC60下,默认方式下建立的是ANSI编码的工程(注:编译的exe内部,其资源字符是以UNICODE保存)
建立UNICODE编码工程的方法:
1、为工程添加UNICODE和_UNICODE预处理选项。 
  具体步骤:打开[工程]->[设置…]对话框,在C/C++标签对话框的“预处理程序定义”中去除_MBCS,加上_UNICODE,UNICODE。(注意中间用逗号隔开)。
  在没有定义UNICODE和_UNICODE前,所有函数和类型都默认使用ANSI的版本;在定义了UNICODE和_UNICODE之后,所有的MFC类和Windows API都变成了宽字节版本了。
2、设置程序入口点
  因为MFC应用程序有针对Unicode专用的程序入口点,我们要设置entry point。否则就会出现连接错误。
  设置entry point的方法是:打开[工程]->[设置…]对话框,在Link页的Category:Output类别的Entry Point里填上wWinMainCRTStartup。

程序员的几个编程习惯:
1、用THCAR代替char
2、字符串加_T(""),如_T("你好")
3、用_tcscpy等代替strcpy等
ANSI操作函数以str开头,如strcpy(),strcat(),strlen();
Unicode操作函数以wcs开头,如wcscpy,wcscpy(),wcslen();
ANSI/Unicode互为兼容的操作函数以_tcs开头 _tcscpy(C运行期库);
ANSI/Unicode互为兼容的操作函数以lstr开头 lstrcpy(Windows函数);
考虑ANSI和Unicode的兼容,我们需要使用以_tcs开头或lstr开头的通用字符串操作函数。

这样,你在ANSI/UNICODE环境下编译时,可以不修改代码。

ANSI/UNICODE下的字符转换和其它
1、在ANSI下,如果程序本身产生的字符(串),如在代码中直接赋值的CString str = _T("你好"),不需要转换,但是,字符(串)是从其它地方来的,如读取UNICODE编码的文件,通信接收的UNICODE数据,则需要转换,转换使用上面两个函数。

2、同理,在UNICODE下,如果程序本身产生的字符(串),如在代码中直接赋值的CString str = _T("你好"),不需要转换,但是,字符(串)是从其它地方来的,如读取ANSI编码的文件,通信接收的ANSI数据,则需要转换,转换使用上面两个函数。

3、不管是ANSI,还是UNICODE,在资源中的字符串,如String Table中的、对话框的静态文本,都不需要转换,因为它们编译后是以UNICODE保存在.exe中的。
对话框上的汉字,只要是简繁同形的,同一个.exe运行在简体Windows和繁体Windows下都可以正常显示,当然两者必须要有对应的字体(库),都用System字体是可以的,或者简体Windows下用“宋体”,繁体Windows下用“新細明體”。简体的“中”和繁体的“中”字体相同,是简繁同形,简体的“国”和繁体的“國”字形不同,是简繁异形。

4、另外,同一个字符串在ANSI和UNICODE下计数个数不同。如“123你好”,在ANSI下是7个字符,在UNICODE下是5个字符。使用CString 的.GetLength()时要特别注意。

ANSI与UNICODE编码的体验

1、你用Windows下的记事本新建立一个文件,输入一段文字,如“123abc你好”,你可以在任何时间双击打开它,可以看懂里面的文字。 
2、再打开该记事本,选“文件->另存为”,在对话框的“编码”中选“Unicode”,保存,你可以在任何时间双击打开它,可以看懂里面的文字。

第1步建立的是ANSI编码文件,保存的汉字是GB2312/GBK汉字(ANSI编码),每个汉字占2个字节,数字字母是ANSI字符,每个字符占1个字节。

第2步建立的是UNICODE编码文件,保存的汉字是GB18030汉字(UNICODE编码),每个汉字占2个字节,数字字母是UNICODE字符,每个字符占2个字节。

3、用十六进制编辑器,如UltraEdit,分别打开上面的两个文件,在十六进制下比较,你会发现其中的奥妙,还有,你再比较这两个文件所占的字节数(不等于字符数)。提示:UNICODE文本文件以0xFE、0xFF开头。

时间: 2024-12-18 20:04:54

宽字符,Ansic和Unicode的相关文章

宽字符wchar_t和窄字符char——putwchar、wprintf

宽字符wchar_t 与 窄字符char 先说下窄字符char,这个大部分读者应该很清楚,char类型的变量占一个字节(byte)(也就是8个bit(比特)),能表示256个字符,那char的范围有两种 第一种(signed char):-128~127 第二种(unsigned char):0~255 (对char的范围感兴趣的读者可以看一下这篇文章:浅谈char类型范围) 但C标准并没有规定char 应该是unsigned还是signed,C标准定义了三种类型:char.signed cha

宽字符、多字节、unicode、utf-8、gbk编码转化

今天遇到一个编码的问题,困惑了我很长时间,所以就简要的的了解了一下常用的编码类型. 我们最常见的是assic编码,它是一种单字节编码,对多容纳256个字符. 我们在编程的时候经常遇到unicode,unicode是一种宽字节编码,能够很好的融合世界各个国家的字符,具有国际通用性,所谓宽字符其实使用两个字节来表示一个符号. 而utf8是一种多字节编码,一个字符所占用的字节数不确定,是对unicode的精简版本,也用具有世界通用性.Gbk也是一种双字节编码,其实就是对中文简体的一种编码,不具有世界通

通过编写串口助手工具学习MFC过程——(三)Unicode字符集的宽字符和多字节字符转换

通过编写串口助手工具学习MFC过程 因为以前也做过几次MFC的编程,每次都是项目完成时,MFC基本操作清楚了,但是过好长时间不再接触MFC的项目,再次做MFC的项目时,又要从头开始熟悉.这次通过做一个串口助手再次熟悉一下MFC,并做了一下记录,以便方便以后查阅.做的过程中多是遇到问题直接百度和谷歌搜索来的,所以很多都是不求甚解,知其然不知其所以然.另外做此工具只是为了熟悉了解,许多功能还没有完善!(开发工具VS2008) (三)Unicode字符集的宽字符和多字节字符转换 在上一节<(二)通过&qu

彻底弄懂UTF-8、Unicode、宽字符、locale

目录 Unicode.UCS UTF8 结论: 宽字符类型wchar_t locale 为什么需要宽字符类型 多字节字符串和宽字符串相互转换 最近使用到了wchar_t类型,所以准备详细探究下,没想到水还挺深,网上的资料大多都是复制粘贴,只有个结论,也没个验证过程.本文记录探究的过程及结论,如有不对请指正. Unicode.UCS UCS(Universal Character Set)本质上就是一个字符集. Unicode的开发结合了国际标准化组织所制定的?ISO/IEC 10646,即通用字

宽字符与Unicode (c语言 汉语字符串长度)

在C语言中,我们使用char来定义字符,占用一个字节,最多只能表示128个字符,也就是ASCII码中的字符.计算机起源于美国,char 可以表示所有的英文字符,在以英语为母语的国家完全没有问题. 但是世界上存在很多不同的语言,例如汉语.汉语.日语等有成千上万个字符,需要用多个字节来表示,称之为宽字符(Wide Character).Unicode 是宽字符编码的一种,已经被现代计算机指定为默认的编码方式,Windows 2000以后的操作系统,包括Windows 2000.XP.Vista.Wi

字符编码(续)---Unicode与ANSI字符串转换以及分辨字符编码形式

Unicode与ANSI字符串转换 我们使用windows函数MultiByteToWideChar将多字节字符串转换为宽字符字符串,如下: int MultiByteToWideChar( UINT uCodePage, DWORD dwFlags, PCSTR pMultiByteStr, int cbMultiByte, PWSTR pWideCharStr, int cchWideChar); uCodePage参数标识了与多字节字符串关联的一个代码页值.dwFlags参数允许我们进行额

宽字符

1.宽字符是为了解决国际化,英文软件写好后,要发行到不同的国家,这时就需要使用宽字符,宽字符能把汉字当成一个字符. 2.字符集 <1>多字节字符集  (窄字符) <2>Unicode字符集(用来解决国际化)(宽字符) 3.MessageBox    MessageBox引用了windows.h文件. 宽字符与窄字符的区别:窄字符1字节,窄字符2字节. MessageBox这个函数与 设置有关,默认是unicode,这个设置应该只影响MessageBox函数吧. 宽字符有一个宏指令 

多字节字符与宽字符重新认识

一直都说,多字节字符,何为多字节,并不只是一个char就是了.英文的字符都是char能表示,但是中文字符,是2个字节表示的. 所以, char s[] = "ha哈哈";     int l = strlen(s);// 6     char c = s[2];// -71 '?' cannot represent s 是占7个字节. s[2]只是'哈'的前半部分,所以决不能写这样的比较代码!!!: if (s[2]=='哈') 所以,字符串中有中文时,一定要格外小心. 甚至,所有的C

多字节字符和宽字符

多字节字符和宽字符 开发多语言版软件,经常会碰到字符编码的问题,看了很多资料都说得不是很清楚,终于碰到一篇讲的不错的文章跟大家分享一下!(时间关系,翻译了重点部分) char型和wchar型 在日文版Windows上我们用到字符编码是Shift-JIS,主要的用1byte表示英数字,2byte表示日文字符,这种编码表示的字符称作多字节字符.(中文版Windows字符编码:GB2312) char数组的字符 世界上主流的标准字符编码是Unicode,在Windows上,英数字,日文字符,中文字符,