字符编码详解
字符编码详解
目录
字符编码的程序兼容
乱码问题
可能是语言兼容出问题、也有可能是程序兼容出问题
乱码类型与产生原因
名称 | 示例 | 特点 | 产生原因 |
---|---|---|---|
古文码 | 浣犲ソ涓栫晫 (utf你好世界) | 大都为不认识的古文,并加杂日韩文 | 以GBK方式读取UTF-8编码的中文 |
口字码 | ![]() ģºÊÀ½(md里打不出来) | 大部分字符为小方块 | 以UTF-8的方式读取GBK编码的中文 |
符号码 | ä½ å¥½ä¸ç (utf你好世界) | 大部分字符为各种符号 | 以ISO8859-1方式读取UTF-8编码的中文 |
拼音码 | ÄãºÃÊÀ½ç (gbk你好世界) | 大部分字符为头顶带有各种类似声调符号的字母 | 以ISO8859-1方式读取GBK编码的中文 |
问句码 | 由月要好好学习天天向?? | 字符串长度为偶数时正确,长度为奇数时最后的字符变为问号 | 以GBK方式读取UTF-8编码的中文, 然后又用UTF-8的格式再次读取 |
锟斤拷 | 锟斤拷锟斤拷要锟矫猴拷 学习锟斤拷锟斤拷锟斤拷 | 全中文字符,且大部分字符为"银斤拷"这几个字符 | 以UTF-8方式读取GBK编码的中文, 然后又用GBK的格式再次读取 |
编译器和系统的乱码原因
软件乱码
锟斤拷与数组越界
microsoft编译器下c/c++程序可以正常输出汉字但数组越界时却是锟斤拷
手持两把锟斤拷 口中疾呼烫烫烫 脚踏千朵屯屯屯 笑看万物锘锘锘
utf8的带Bom与不带Bom
乱码问题——不可逆乱码(GBK转UTF8)
不可逆乱码问题
用Notepad++的编码工具,在UTF-8文件下,使用GBK编码时,会提示:
【无法恢复警告】
你将要保存当前的修改。
所有修改都是不可逆的。
继续?
> 是 (Y) > 否 (N)
当选择是以后,当再转换回UTF-8编码时,可能会失败,不让你用UTF-8编码编辑。但这不一定会失败,也可以成功
这点让我很疑惑,能不能相互转换就像是薛定谔的猫一样,但我注意到——这可能是由于互相转换时对文本进行了特定的修改所引起的
utf和gbk之间的转换并非一定不可逆,以前我就是使用Notepad++进行gbk和utf8来回互转来研究编码问题
编码显示与编码转换
Notepad++中的编码菜单有两种
- 使用UTF-8编码,使用GB等编码
- 可逆性:可逆
- HEX影响:变化
- 转换UTF-8编码
- 后果:
- HEX影响:无影响
GBK转UTF-8乱码,为什么不可逆
如上图,其中GBK转UTF-8乱码不可逆
总结:由于UTF-8的特殊编码方式,所以有些序列是不可能出现在UTF-8编码中的
所以当我们将由GBK编码的12个字节试图用UTF-8解码时会出现错误,由于GBK编码出了不可能出现在UTF-8编码中出现的序列,所以当我们试图用UTF-8去解码时,经常会遇到这种不可能序列,对于这种不可能序列,UTF-8把它们转换成某种不可言喻的字符“ ”,当这种不可言喻的字符再次以UTF-8进行编码时,他们已经无法回到最初的样子了,因为那些是UTF-8编码不可能编出的序列。然后这个神秘字符再转换成GBK编码时就变成了“锟斤拷”。
编码之——系统与程序
文本行结尾——回车字符与换行符
操作系统的行结束符
Windows文本文件每行都以回车字符和换行符
结尾
系统对应的行结束符 | 简称 | 英语 | 翻译 | 转义表示 | HEX编码 |
---|---|---|---|---|---|
Unix | LF | Line-Feed | 换行 | \n | 0a |
Windows | CRLF | Carriage-Return Line-Feed | 回车换行 | \r\n | 0d0a |
回车符与换行符
判断换行符:用HexEditor打开。如果换行的部分为0d0a,则是Windows文本文件;若仅是0a,则是Unix文本文件
符号 | 转义符号 | ascii编码 | 英文 | 字符类型 |
---|---|---|---|---|
回车符 | \r | 1310、0d16 | Return | 操作字符 |
换行符 | \n | 1010、0a16 | NewLine | 操作字符 |
空格(参考) | 空格 | 4810、2016 | Space | 打印字符(ascii>=32) |
程序读文件时对换行符的处理
- 通常
C++
和Python的文本模式
等程序读取文件时都会自动将这两个字符转换为换行符\n
,并在写入文件时执行相反的转换 - 这种暗地里的修改对 ASCII 文本文件没有问题,但会损坏
JPEG
或EXE
这样的二进制文件中的数据。使用二进制模式读写此类文件时要特别小心
C++强制使用指定编码输出(Qt)
以Qt为例
qDebug()
<<"你好世界"
<<"\344\275\240\345\245\275\344\270\226\347\225\214"
<<QString::fromLocal8Bit("你好世界")
<<QString::fromUtf8("你好世界");
QPushButton *btn = new QPushButton(QString()
+"你好世界"
+"\344\275\240\345\245\275\344\270\226\347\225\214"
+QString::fromLocal8Bit("你好世界")
+QString::fromUtf8("你好世界"),this);
// MinGW编译结果
// 你好世界 你好世界 "浣豺少滑旃暲" "你好世界"
// MSCV编译结果
// ???????? 你好世界 "你好世界" "????????"
修改系统编码后的编译结果(Qt)
这里修改系统编码为utf8
数据库管理对编码的选用
我最早接触到要区分utf8/16/32的场景就是在创建数据库的时候
这几种Unicode的区别详见前面Unicode以及其变形一节
utf8 带 BOM
简概
参考:
BOM:byte order mark,定义字节顺序,因为网络传输中分为两种,大头和小头。uft-8不需要bom表明字节顺序,但可以用BOM来表示编码方式,windows就是采用bom来标记文本文件的编码方式的。
bom是为utf-16和utf-32准备的,用于标记字节顺序。微软在utf-8中使用bom是因为这样可以把UTF-8和ASCII等编码区分开来,但这样的文件在windows之外的操作系统里会带来问题。
不含bom的UTF-8才是标准形式。「UTF-8」和「带 BOM 的 UTF-8」的区别就是有没有 BOM。即
wiki定义
字节顺序标记(英语:byte-order mark,BOM)是位于码点
U+FEFF
的统一码字符的名称。当以UTF-16或UTF-32来将UCS/统一码字符所组成的字符串编码时,这个字符被用来标示其字节序。它常被用来当做标示文件是以UTF-8、UTF-16或UTF-32编码的标记。字节顺序标记通常有几种涵义[1]:
字节顺序标记的使用是选择性的。它的存在会干扰那些不希望文件开头出现非ASCII字符、但可以用其他方式处理文字流的软件对于UTF-8的使用。
使用
- 字符U+FEFF如果出现在字节流的开头,则用来标识该字节流的字节序,是高位在前还是低位在前。
- 如果它出现在字节流的中间,则表达零宽度非换行空格的意义,用户看起来就是一个空格。
- 从Unicode3.2开始,
U+FEFF
只能出现在字节流的开头,只能用于标识字节序,就如它的名称——字节顺序标记——所表示的一样;除此以外的用法已被舍弃。取而代之的是,使用U+2060
来表达零宽度无断空白。举例
略
文件区别、网页区别
- 文件区别:看文件开头有没有 U+FEFF
- 网页区别:UTF-8 的网页代码不应使用 BOM,否则常常会出错。这是一个小例子: 为什么这个网页代码
<head>
内的信息会被浏览器理解为在<body>
内?
什么时候要BOM?
应用1:Qt中文设置
另外,在代码编辑页面右键,最下面会有个选项 “Delete UTF-8 BOM on Save”
应用2:Notepad编辑代码导致的乱码
应用3:AutoHotKey输出中文字符串乱码
参考:https://zhuanlan.zhihu.com/p/472008013
将文件另存为编码为 “带bom的UTF-8" 文件即可
改Windows系统编码为utf8
好处与坏处
- 好处
- 1.解决由utf8引起的cmd,powershell等乱码问题
- 2.Visual Studio 新建文件则默认为utf8
- 3.其他
- 可能的坏处
- 上古版本的第三方应用软件可能会出现乱码
- 设置声明
- 由于此设置,微软官方特别说明为【beta版】(截至时间
20181003,20210413) - 可能会引起其他未知问题,请充分考虑后再决定是否设置
- 由于此设置,微软官方特别说明为【beta版】(截至时间
设置步骤
- 设置步骤(win10)
- 小娜搜索【更改国家或地区】> 语言 > 右侧的 “管理语言设置” > 弹出新窗口 "区域"
- > 管理 > 更改系统区域设置 > 勾选下面的Beta版:使用Unicode UTF-8 提供全球语言支持(上面那个区域设置不用管)
- 按确认后会让你重启一遍电脑,重启即可
我个人设置后出现问题的程序
乱码但功能不受损的
有道词典
翻译出来的中文结果中的字有几率乱码掉几个字
易语言
文字显示乱码,但还能用
直接进入不了程序的
Rolan(v1旧版,新版不受影响)
直接打不开。黄色警告:Run-time error '383': 'Text' property is read-only
题外话:
由于不能用了,于是我去找更新,才发现都出到第三版了(虽然还在Beta),而我之前还在用第一版。新版可以正常使用没有错误
不过吧,官网已经不提供第一版的下载了,第2版其实也没好用到多少,主要是免费版可以建的分类是有限的,只有8个,而初版能分无限个
而且第2版的UI宽很多,我个人不太喜欢
第二版收费,49/年
然后我就去找替代品了:CLaunch,除了难上手以外功能很强,而且高度面向开发人员看原理
图吧工具箱
直接打不开
小栗子框架
直接打不开
Autodesk CAD报错
依次报错:
【vl.crx ARX 命令中发生异常】
Unhandled Exception e06d7363(e06d7363h) at address a245a839h
【AutoCAD】
此版本的AutoCAD安装不正确,有些功能可能无法正确运行。请立即重新安装AutoCAD以确保所有功能均可正常使用是否仍要继续?
然后自动关闭软件