ASCII是最基本的编码,它定义了0~127对应的字符,包括最基本的英文字母、标点符号。它无法表示中文。ASCII编码的文本,每一个字节都是0~127,如果某个字节大于127,那它一定不是ASCII编码。
为了用计算机记录并显示中文,中国人发明了GB系列编码。GB系列编码定义了中文汉字、标点的编码。按照GB系列编码,在一段文本中,如果一个字节是0~127,那么这个字节的含义同ASCII编码,否则,这个字节和下一个字节共同组成汉字(或是GB编码定义的其他字符)。因此,GB系列编码向下兼容ASCII,也就是说,如果一段用GB编码文本里的所有字符都在ASCII中有定义,那么这段编码和ASCII编码完全一样。GB编码早期收录的汉字不足一万个,基本满足日常使用需求,但不包含一些生僻的字,后来在一个个新版本中加进去。最早的GB编码是GB2312,后来有GBK,最新的是GB18030,加入了一些国内少数民族的文字,一些生僻字被编到4个字节,每扩展一次都完全保留之前版本的编码,所以每个新版本都向下兼容。
同样,日文、韩文、世界各国文字都有了它们各自的编码(如果ASCII不能满足使用要求的话)。这些编码都和GB编码相似,兼容ASCII并用两个字节表示一个字。所有这些各国文字编码,微软统称为ANSI 。所以即使知道是ANSI,我们还需要知道这是哪国文字才能解码,因为这些编码都互相冲突。另外,你无法用一段ANSI 编码表示既有汉字、又有韩字的文本。
严格来说ANSI 不是字符编码,而是美国一个非营利组织,他们做了很多标准制定工作,包括C语言规范ANSI C,还有各国文字编码对应的“代码页”(code page)。ANSI 规定简体中文GB编码的代码页是936,所以GB编码又叫做ANSI code page 936(按ANSI标准的代码页936),各国编码被统称为ANSI 由来于此。对于这些乱七八糟互相冲突的多国字符编码,有个统称还是不错的,下面讨论姑且继续使用ANSI 。
(控制面板->语言区域->格式设置,如中文简体,中国)
==Unicode / UTF / UCS==
为了解决冲突的问题,就有了Unicode(万国码,统一码)——一种将全世界所有语言所有字符都收录在一起、让它们和平共处的编码……。Unicode虽是一种字符编码,但严格来说它和GB18030不能相提并论:它只定义了每一个字符对应一个整数(目前包含了十万多个字符,其中0~127和ASCII完全一样),但它没有定义这个整数如何变成字节。当你告诉我这段数据是Unicode编码,啊,不好意思,我还是不知道该怎么解码——因为变成字节流的格式不只一种,它们都叫做“Unicode转换格式”(Unicode Transformation Format,简称为UTF)。
所以这里面就有了一大堆UTF:UTF-8、UTF-8 with BOM、UTF-8 without BOM、UTF-16、UTF-16LE、UTF-16BE…… 还有很少见的UTF-32、,早期还会听说过UCS-2、UCS-4…… (:з」∠)
等等,为什么Windows记事本里有个保存选项是Unicode?这个稍后说。
先说最常见的UTF-8:它将一个字符编为1-4个字节,其中一个字节的字符和ASCII 完全一致,所以它也向下兼容ASCII。和ANSI类似,UTF-8第一个字节决定了之后多少个字节是一组好基友。多数汉字在UTF-8里为3个字节,有一些生僻的汉字会编到4字节。
我们迎来第一种不兼容ASCII的编码:UTF-16。UTF-16以每2个字节为一个单元,每个字符由1-2个单元组成,所以每个字符可能是2个字节或者4个字节,包括最常见的英文字母都会编成两个字节。大部分汉字也是2个字节,少部分生僻字为4个字节。UTF-16还有讲究,一个单元中的两个字节的顺序不是唯一的。学过计算机原理的同学知道,计算机中表示一个整数分两种格式:低位在前高位在后,或者反过来。例如用两个字节表示260这个整数,可能是:
低位在前:04 01 (260=4+256*1)
高位在前:01 04 (260=256*1+4)
低位在前的UTF-16叫UTF-16LE,高位在前的叫UTF-16BE。目前绝大部分的计算机系统都使用低位在前的整数格式,所以如果没有声明,UTF-16默认是LE。
早期Unicode收编的字还不多时,两个字节足够表示所有字符,所以有一种固定为两个字节的UTF,叫UCS-2。UTF-16的两个字节部分和UCS-2完全一样,所以UTF-16向下兼容UCS-2。UCS-2同样分LE和BE。而Windows的记事本还有Windows其它地方所谓的Unicode,当代的Windows里其实是UTF-16LE,在Windows XP和更早的版本里是UCS-2LE。微软(又是微软)正是混淆Unicode概念的祸首,微软你这么讨厌你家人知道吗?
此外,UTF-32和UCS-4固定为4个字节一个字符,同样分LE和BE。
还没完,这么多字符编码,软件打开时如何知道是哪个编码?于是不知道谁蹲坑时想出了BOM:在一个文本文件或者一段字符编码前加上几个固定的字节用于识别,这些字节保证不对应任何一个字符,所以软件一读就能验明正身:
EF BB BF - 我是UTF-8
FF FE - 我是UTF-16LE
FE FF - 我是UTF-16BE
(没有BOM,直奔主题)-你猜?
不错,没BOM只能靠猜了。软件读入文件时可以所有编码都试一下,看哪个像。另外,BOM只针对Unicode系列编码,ANSI通通不会有BOM。很显然,没有BOM难免偶然猜错。网上就流传了一个神奇的段子:打开Windows记事本,打入“联通”两个字,保存,关闭,再打开,变成了个黑块。记事本用ANSI(GB18030)保存联通这两个字,刚好这两个字的GB18030编码看起来很像UTF-16,于是就当成UTF-16来打开……
(在简体中文Windows中,默认的代码页是 GBK (ANSI code page 936),不是 GB18030 (ANSI code page 54936)。)
BOM听起来很不错,但实际是个讨厌的设计,因为它和很多协议、规范不兼容,这是题外话。
于是,UTF-8 with BOM、UTF-16 without BOM 你们就懂了。等等,如果不提BOM,究竟有BOM还是没有BOM?—— 又是一个十分纠结的问题,Windows里的软件一般都默认有BOM,而其它系统都默认没有BOM——可能是因为Windows常要兼容ANSI的原因,特别依赖BOM来防止会错意。
==谁是正统==
这么多种编码,用来写文章就罢了,打开个文档看到乱码就退出、换个程序或者换个编码再打开;但写程序时可半点马虎不得,各种程序开发环境对编码支持都不一样,如果编码没搞好,你写好的程序可能在别人计算机上就运行不起来了。如果我开发跨平台的代码,而且要有中文(注释),哪用什么编码好?以下是我所知道各开发环境/编译器支持常见编码情况(所有=ANSI、UTF-8 BOM and no BOM、UTF-16LE BOM and no BOM):
Visual Studio:所有,保存默认ANSI 。
VC编译器:所有,除了UTF-8 without BOM(直接当成是ANSI )
Windows记事本:所有,保存默认ANSI,无法保存无BOM。
XCode:只支持 UTF-8 without BOM。
GCC:所有
vim:所有,保存默认为系统默认编码,一般是UTF-8 without BOM。
Eclipse:所有,保存默认不明,Mac下居然是ANSI (我们中出了个叛徒)。
ANSI是无法跨境的,用GB写的文档拿去韩国就果断乱码了。光是简体中文系统,ANSI 也是经常被认错的,Eclipse里经常(不总是)出现打开ANSI 文件是乱码的情况,这是因为ANSI 没有很明显的特征。XCode和Mac的文本编辑器打开ANSI 直接是乱码,因为明确不支持。ANSI 容错性普遍比较差,一个字节错了可能导致后面的字通通挂掉。为了防止Eclipse等发神经,也为免跨国带来麻烦,更为了你自己的数据安全,请远离ANSI。
UTF-16不兼容ASCII,不兼容C语言的字符串处理库函数(因为字节流里有\0),除了Windows爱用,其它系统都痛恨它。BOM和很多协议规范冲突,很多软件都抵制,也是只有Windows常用,而且将其列为正统(作反)。
综上,跨平台开发请使用UTF-8 without BOM,那是最通用的编码,是很多软件系统的默认编码,你在看的网页也用它。它特征明显,除了VC编译器和微软的各种软件外暂时没发现哪个软件会有认错的情况。它还有经过精心设计的容错机制,错一个字节最多只会错一个字符。请手动设置你的开发环境,将默认保存的编码设为UTF-8 without BOM,并将其它编码的文件转换过来,乱码就拜拜啦;记事本等不支持的编辑器,不要让他们摸你的文件。至于VC编译器硬要闹别扭就由它去吧 (:з」∠)
(经过测试,VS2010能正常打开UTF-8 without BOM的代码,但可能编译不通过,并报奇怪的编译错误)
写在最后:
所有苹果软件只支持UTF-8,和ANSI还有一大堆不统一的编码一刀两段。 微软到今天还抱着ANSI不放。
Unicode和ANSI是两种不同的字符编码方式。Unicode(统一码、万国码、单一码)使用全16位元字元集来表示字符,而ANSI编码通常使用 0x80~0xFF 范围的 2 个字节(8位)来表示 1 个字符。对于字符来说ANSI以单字节存放英文字符,以双字节存放中文等字符,而Unicode下,英文和中文的字符都以双字节存放。有些Unicode字符无法用ANSI编码来表示,因此文件中含有Unicode格式的字符保存为ANSI编码的文本时,该Unicode字符将丢失或被错误表示。这样文本保存以后,再次打开将会发现里面少了一些内容或是会出现乱码。
所以,有时会发生“…该文件有Unicode格式的字符,当文件保存为ANSI编码的文本时,该字符将丢失…”的问题
ANSI码(American National Standards Institute),中文:美国国家标准学会的标准码。 为使计算机支持更多语言,通常使用 0x80~0xFF 范围的 2 个字节来表示 1 个字符。比如:汉字 中 在中文操作系统中,使用 [0xD6,0xD0] 这两个字节存储。 对于ANSI编码而言,0x00~0x7F之间的字符,依旧是1个字节代表1个字符。这一点是ANSI编码与Unicode编码之间最大也最明显的区别。比如“A君是第131号”,在ANSI编码中,占用12个字节,而在Unicode编码中,占用16个字节。因为A和1、3、1这4个字符,在ANSI编码中只各占1个字节,而在Unicode编码中,是需要各占2个字节的。C语言1. C是高级语言。它把高级语言的基本结构和语句与。
文件含有Unicode格式的字符,当文件保保存为ANSI编码的。
ANSI编码不兼容UNICODE编码, 需要将文件转换为国标编码就没问题了,国标编码兼容ANSI编码。一旦转换后,信息将丢失,无法恢复,只能用原文件处理。或者看看你用的工具是否支持UNICODE编码的文本文件。支持的话保存就没问题。 正常,因为ANSI编码并不包括所有字符,如果文档里有一些特殊符号或其他语言的文字时,就有可能丢失。这是正常的。处理方法:。
(已解决)从网页下下载的txt文本文件默认是ANSI编码的,。
我就是想问下文本文件的默认编码是由什么决定的、 。
什么叫unicode编码?什么叫ANSI编码?
unicode 就是将世界上所有的文字用2个字节统一进行编码。ANSI是系统默人编码。
ansi编码与unicode有什么联系吗?如果有我该如何转换呢? - 。
可以使用windows的函数MultiByteToWideChar,WideCharToMultiByte做相互转换. 下面是关于这两个函数的说明. 如果使用delphi编个程序转换,可以使用StringToWideChar和WideCharToString两个函数实现.
开始——所有程序——附件——命令提示符,打开命令提示符,输入chcp,按回车键执行,会查询当前系统的活动代码页,它指明了当前系统使用的编码。
想要更改默认使用的编码方式,可尝试以下步骤,
1. 打开 控制面板(Control Panel)
2. 打开 时钟、语言和区域 (Clock, Language and Region)
3. 点击 区域 (Region)
4. 选择 格式(Format) 选项卡,并将格式 改为 Chinese (Simplified, China) (这个其实可以不改,看你的喜好,更改此处会更改时间显示方式如 把日期 改为 YYYY/MM/DD 等,有些程序会通过此项来选择所显示的语言。重点的从第五步开始)
5. 然后 点击打开 管理(Administrative) 选项卡
6. 点击 更改系统区域设置 (Change system locale…) 按钮 (若出现用户账户控制对话框,请选择“允许”或“是”或者“确定”)
7. 将区域设定 改为 Chinese (Simplified, China) 然后 点击确定,并重新启动计算机。
另外对于你说的txt文件。Windows 自带的记事本(Notepad.exe)会默认采用 ANSI 编码来处理文本文件,这也是由于大部分的文本文件都是用的各国自己的编码标准写成的。这个ANSI 编码的具体编码方式,也会因上面所讲述的设置变化而有所改变。若想要摆脱不同的 ANSI 编码所产生的困扰(如在中文的系统上写的TXT文档要在日文的系统上打开经常会出现乱码),可以在保存文本文件时 选择采用 UTF-8 (单字节8位的Unicode编码)。
另外,通过 Web浏览器(如 Internet Explorer)打开文本文档时,可以给你机会(如在页面上单击鼠标右键)选择你认为应该选择的编码方式。
不过遇到一个用户的电脑,原来ANSI编码的ini文件里的中文是正常的;用着用着,某一天就乱码了,无法识别ANSI编码文件里的中文。他的的系统区域设置已经是 中文(简体,中国)了。所以乱码的问题应该于此无关了。
英文系统下是: Chinese (Simplified, China) ,
中文系统下是:中文(简体,中国)
不过在cmd.exe输入chcp命令查询到当前系统的活动代码页为437,竟然不是936。
输入:chcp 437 按回车键执行命令→原有的中文也变成问号了,这是由于不识别中文的缘故。
该命令的作用是更改代码页(437 是美国英语的代码页)。
再输入:chcp 936 按回车键执行命令。
(936是中文的代码页),也是中文系统cmd默认的代码页。又回显中文了。
chcp 是 “change code page”(更改代码页)的缩写,想要知道当前的活动代码编号可以输入:chcp /?查看。
C:\WINDOWS\system32\cmd.exe
如上所说,Windows 在处理文字时,会将ANSI编码转换成Unicode编码。这回使一些原因ANSI编码不兼容而出现的乱码因已转成Unicode,使其即使在系统已改成正确ANSI设置后依然无法恢复。
例如 “你好”的GB2312编码的文本,采用西欧编码解码的话会变成ÄãºÃ. 这时,系统可能会认为ÄãºÃ就是正确的字符,并将其记录成Unicode编码的文本,这样会导致它会一直保持ÄãºÃ状态。
所以对于这种已经定型的乱码(往往出现在,快捷方式,文件名等处),需要,将其复制到Word中,然后将其另存为成*.txt文件,然后在保存时,选择西欧编码方式。然后再用 GB2312 打开文本文件,就可恢复文本文件的内容。
notepad++是程序员非常喜欢的轻量级文本编辑器,它支持多种程序语言,代码缩进语法高亮、代码自动补全等等。
但是默认程序主题比较亮(适合于在光线比较明亮的室外),长时间注意伤眼,我们可以调整为不是那么刺眼的主题,如monokai黑色主题。
程序默认的编码为系统编码,windows一般是ANSI编码,都有时我们需要在其它设备使用比如Linux,这就需要我们的文件格式编码为utf-8。但是每次都去修改很麻烦,我们需要将默认编码更改为utf-8。(设置->首选项->创建->新建文档的编码选择“utf-8无BOM”,勾选“应用于打开ANSI文件”)