2 mr qqq Mr_QQQ 于 2015.07.25 10:09 提问

关于计算机字符编码的问题!

计算机字符编码一直困扰我,真希望有大牛帮我解惑:
1. 输入法在输入文本的时候其实是输入对应字符编码集的对应字符的二进制编码,那么这时如果要保存,只需要保存这些二进制字节就可以了,读的时候用输入时使用的编码集解码即可,为什么还有选择保存字符编码这一项,以上只是我的理解。比如:
在windows中使用记事本时,我们输入:
你好,世界!
这时我们使用的是输入法在当前环境中默认的字符编码方式进行输入的,那么我们 需要直接保存即可,但保存时有额外选项,即选择编码方式的选项:
图片说明
假如我们选择不与当前默认编码方式一样的编码方式保存,为什么重新读取时还是一 样的字符,即还是:
你好,世界!
我是这样理解的,假如我们默认编码为a , 保存时用的编码是b , a和b使用的字符集不 一样我们输入法输入汉字时,用的是编码a , 保存时用的是编码b , 那么我们读取时计 算机会判断其保存时的字符编码是b , 就先以b解码,解码后的字节以系统默认编码 方式编码。
问题来了,以上理解对吗?不管怎么选择保存时的编码,最终的显示汉字还是以输入 法输入时的编码方式解码的,那么保存时选择保存编码方式这一项有必要吗。
2 , Unicode和GB的一些字符编码集的汉字编码对应的字节不是一样的,对吗?
3 , 现在我们做项目总喜欢用UTF-8来传输数据,UTF - 8对应的字符编码集就是Unic ode,但其汉字用3个字符,其实在中国是很浪费的,是吗?

6个回答

lm_whales
lm_whales   Rxr 2015.07.25 12:07

早期文本文件,只是按照字符编码存储数数据
后来有些文本文件,对于UNICODE 编码,
额外加两个字节的 UNICODE 标志 ,我记得是 0xFFFE,或者0xFEFF
至于UTF8 编码,有没有标注不清楚
UTF8编码,是不等长编码

UNICODE ,ASCII 编码是等长编码
ASCII实际上表示不了汉字,
不过后来才采用 一种编码方式,汉字两个字节,字符1个字节,
当时叫 MBCS 即多字节编码,这时候文本文件里存汉字的话
其实是MBCS 编码的文件,没有汉字这种多字节字符的文件,
等同于ASCII码文件。
有了汉字的其实是MBCS 文件。不再是等长编码

lm_whales
lm_whales   Rxr 2015.07.25 12:17

UTF8按需要编码,从文件角度决度考虑,其实还好,因为三字节编码,多为生僻字
最麻烦的还是字符处理
内存中的字符字节数是不等长的,
不能确定一定字符数的汉字,
用多少字节存储,
也不能确定一定字节的汉字,实际包含多少字符
必须联系实际汉字才知道。这样很不方便。
所以,其实UTF8 处理汉字,
并不好,同MBCS一样,甚至还要差一点。

zuishikonghuan
zuishikonghuan   2015.07.26 09:11

1。也对,也不对
首先输入法输入到编辑框的字符只能是Ansi和UTF-16两种,这和输入法无关,和Windows的编程模式有关,Windows桌面程序创建窗口时,只能创建ANSI窗口和unicode(UTF-16)窗口,如果输入法不输入当前窗口用的编码,那么显示出的文字就会乱码,也就是说计算机程序会告诉输入法用什么编码,并且只会用这种编码解码。
至于说为何不统一编码,这个是有历史原因的,我写过一篇博客讲win32开发的编码,其中讲道了:

ASCII编码(美国标准信息交换代码)是很早的一种编码,最早的ASCII使用7位表示一个字符,随着计算机在世界范围内的普及,ASCII不能满足人们的需要了,于是,人们开始了对ASCII的扩充之路。

例如,IBM公司将原本7位的ASCII扩充到8位,使其可以标识256个字符,但是这根本不能满足人们的需要,比如中国的文字,根本就不够用。

微软公司推出了一个当时不错的解决方案,那就是Ansi,微软提出了一个叫“代码页”的感念,Ansi在不同的代码页下标识的字符不同,例如,在大陆Ansi表示GBK,GB2312等编码,在台湾表示BIG5编码。用户只需要把系统的代码页(语言和区域设置)设置到自己国家的代码页,就可以很方便地使用自己国家文字的程序和文档了。

但是随着发展,代码页越来越多,国际交流原来越频繁,Ansi又不能满足人们的需要了。于是,Unicode诞生了。

Unicode是一种字符映射方案,是把每一个字符映射成几个字节,不同国家的字符,映射到不同的段中(例如中文映射到0x4E00 - 0x9FBF)因此Unicode有个形象的称呼叫做万国码,UTF-16和UTF-8等都是Unicode编码方式,但是在微软的文档和程序中,Unicode就是指的UTF-16。

2。对

3。是的,UTF-8是可变长度的,存储中文会有一定的浪费,如果没有太特殊的字符,用Ansi是不错的选择

zuishikonghuan
zuishikonghuan 回复Mr_QQQ: 记事本是这样转码的:使用WideCharToMultiByte和MultiByteToWideChar这两个函数,至于说windows是如何实现的我就不知道了,windows曾经泄露出过源码,如果你有可以研究研究
2 年多之前 回复
Mr_QQQ
Mr_QQQ 回复zuishikonghuan: 可是,这样还是有问题,输入法输入的时候是unicode解码,我保存为GBK时电脑是怎么知道Unicode的字和哪个GBK字符对应,它们又不像UTF-16和UTF-8,采用的都是同一个字符编码集,我推测只有可能是一个汉字会对应多种编码集,电脑会选择用户选择的那一种编码集对应的该汉字的字节来保存,这样理解好牵强。。。
2 年多之前 回复
zuishikonghuan
zuishikonghuan 回复Mr_QQQ: 因为用unicode编码时,记事本的编辑框采用unicode解码显示,你保存gbk时,因为记事本知道当前编辑框是unicode编辑框,他把编辑框中你输入的unicode编码的字符在内存中转换成gbk,再写入到文件,所以你再次打开时就不会乱码了,另外记事本可以很方便区分一个文件中的字符是什么编码,因为UTF16和UTF8都有bom,bom就是文件前几个字节是固定的表示字符
2 年多之前 回复
Mr_QQQ
Mr_QQQ 谢谢你的回答,还有个问题,如果输入法用unicode编码,那么如果我保存为GBK的话,由于GBK不是使用Unicode编码的,应该会乱码,而实际上没有乱码,为什么?
2 年多之前 回复
cuiwei1026522829
cuiwei1026522829   Ds   Rxr 2015.07.26 18:10
CSDNXIAOC
CSDNXIAOC   2015.07.25 10:20

UTF-8是Unicode的一种实现方式,也就是它的字节结构有特殊要求,所以我们说一个汉字的范围是0X4E00到0x9FA5,是指unicode值,至于放在utf-8的编码里去就是由三个字节来组织,所以可以看出unicode是给出一个字符的范围,定义了这个字是码值是多少,至于具体的实现方式可以有多种多样来实现。

UTF-8是一种变长字节编码方式。对于某一个字符的UTF-8编码,如......
答案就在这里:计算机字符编码
----------------------你好,人类,我是来自CSDN星球的问答机器人小C,以上是依据我对问题的理解给出的答案,如果解决了你的问题,望采纳。

K346K346
K346K346   2015.07.25 10:46

楼主说的有道理,坐等答案

Csdn user default icon
上传中...
上传图片
插入图片