之前一直在纠结这些格式到底有什么区别,有时候因为格式的问题会让人抓狂。

下面通过实战来分析下:

下面在windows上建立一个txt文档。txt的优势是没有文件头,这样比较好分析。

ANSI格式:

可以看到,0D0A是\r\n,可以忽略,这里的蛤被识别成B8 F2

UTF-8无BOM:

这里的英文字母还是ASCII格式,汉字在这里被识别成 E8 9B A4

UTF-8:

英文字母是ASCII,这里前面多了三个字节: EF BB BF,这个东西可能是BOM

蛤被识别成E8 9B A4

UCS2 大端:

这里有一个前缀 FE FF

这里的0123对应的30,31,32被扩展成两个字节,\r\n也是。

汉字被识别成 86 E4

可以注意到,对于0,识别出 0030,是大端排列的

UCS2小端:

这里有一个前缀 FF FE

另外一个区别是数字和汉字对应的编码是小端排列的

那么这里来总结一下:

1.除了UCS2,其他格式的ASCII字母都是一个字节。

2.UCS2和UTF8都带有前缀

3.对于ANSI和UCS2,汉字被识别成2个字节,对于UTF8,汉字被识别成三个字节(实际上UTF8中,应该随着汉字而变化)。

这里的UCS2不论什么都识别成两个字节,比较变态。

网络上建议为了兼容性,使用无BOM的UTF8

那么有没有BOM有什么区别呢?知乎上这么解答(http://www.zhihu.com/question/20167122):

下面的粗体字都是从这里拷过来的:

UTF-8 不需要 BOM,尽管 Unicode 标准允许在 UTF-8 中使用 BOM。所以不含 BOM 的 UTF-8 才是标准形式

后面又提到:在 UTF-8 文件中放置 BOM 主要是微软的习惯。    这样就释怀了,原来是微软干的,好像系统自带的记事本广受吐槽。

微软在 UTF-8 中使用 BOM 是因为这样可以把 UTF-8 和 ASCII 等编码明确区分开,但这样的文件在 Windows 之外的操作系统里会带来问题。

「UTF-8」和「带 BOM 的 UTF-8」的区别就是有没有 BOM。即文件开头有没有 U+FEFF。

在网页上使用BOM是个错误。BOM设计出来不是用来支持HTML和XML的。要识别文本编码,HTML有charset属性,XML有encoding属性,没必要拉BOM撑场面

其实说BOM是个坏习惯也不尽然很多shell出于兼容的考虑不检测BOM最后回头想想,似乎也真就只有Windows坚持用BOM了。

看起来BOM(EFBBBF)就是让编辑器识别他是UTF8,编辑器如果把它识别为字符的话就会出错。

UTF8的格式如下:

1、对于单字节符号,字节第一位为0,后面7位表示字节编码。

2、对于n字节符号,第一字节的前n位都设为1,第n+1位为0,其余位位编码位置。

上面的蛤的表示是E8 9B A4,它有三个字节,第一个字节前面是1110,也正好符合。

那么什么是UCS2呢?UCS2在windows中指代Unicode。

这里(http://demon.tw/programming/utf-16-ucs-2.html)有解答:

简单的说,UTF-16可看成是UCS-2的父集。在没有辅助平面字符(surrogate code points)前,UTF-16与UCS-2所指的是同一的意思

所谓微软的 Unicode,确实是 UTF-16LE,那就是UCS2 LE了。

这里(http://www.zhihu.com/question/20650946)又讲了:

  • 所谓的「ANSI」指的是对应当前系统 locale 的遗留(legacy)编码。[1]
  • 所谓的「Unicode」指的是带有 BOM 的小端序 UTF-16。[2]
  • 所谓的「UTF-8」指的是带 BOM 的 UTF-8。[3]

原来这里的ANSI实际上是GBK这些编码啊!

而记事本的ANSI编码,就是这种默认编码,所以,一个中文文本,用ANSI编码保存,在中文版里编码是GBK模式保存的时候,到繁体中文版里,用BIG5读取,就全乱套了。

这段话看了之后茅塞顿开啊!没有文件头确实难以知道它是什么编码。

记事本也不甘心这样,所以它要支持Unicode,但是有一个问题,一段二进制编码,如何确定它是GBK还是BIG5还是UTF-16/UTF-8?记事本的做法是在TXT文件的最前面保存一个标签,如果记事本打开一个TXT,发现这个标签,就说明是unicode。标签叫BOM,如果是0xFF 0xFE,是UTF16LE,如果是0xFE 0xFF则UTF16BE,如果是0xEF 0xBB 0xBF,则是UTF-8。如果没有这三个东西,那么就是ANSI,使用操作系统的默认语言编码来解释。

还有一个简单的解释:

Unicode是FFFE后面接着UTF-16字符串的二进制文件,UTF-8是EFBBBF后面接着UTF-8字符串的二进制文件、ANSI是有时候会被解释为当前locale对应的code page的字符串的二进制文件。(还是根据前缀来的啊)

看到这一句话,说明GB开头的也可以无视了:

GB 是国标,中国的一个发布编码规范的机构,可以忽略掉,通用性太差了。微软在 GB2312 的基础上扩展了 GBK,也可以忽略掉。

那么UTF8 without BOM怎么解析呢,没有文件头??

一些代码文件里面一般是在最前面加入了文件格式的说明,比如HTML的charset,python的开头一行也有。

这里有一个回答解决了疑惑(如何自动识别UTF8)

UTF-8 can be auto-detected better by contents than by BOM. The method is simple: try to read the file (or a string) as UTF-8 and if that succeeds, assume that the data is UTF-8. Otherwise assume that it is CP1252 (or some other
8 bit encoding). Any non-UTF-8 eight bit encoding will almost certainly contain sequences that are not permitted by UTF-8. Pure ASCII (7 bit) gets interpreted as UTF-8, but the result is correct that way too.

原来它是智能识别,根据UTF8特定的格式来校验它是否是UTF8

还有一些问题仍未解决的:

Qt中出现的Latin1,ASCII是什么?为什么Qt经常乱码?

1.根据百度百科的介绍,Latin1包含ASCII,具有一些其他的字符。当然了,使用英文的时候这些都可以。

2.local8bit应该是本地编码。QString内部应该要保存UTF8,然后输入输出的时候需要转换一下:

QString str = QString::fromLocal8Bit("汉字");//输入

std::cout << "Local Output:" << str.local8Bit() << endl;//输出

根据这篇博客的介绍:

http://blog.csdn.net/brave_heart_lxl/article/details/7186631

可以看出源代码文件的编码格式对其也有影响。而且QString赋值的时候必须要告诉QString自己是什么编码。

一般给个char*的时候,Qt并不知道你采用的是什么编码,而是需要告诉它你采用的是什么编码。

正确的操作应该这样:

告诉Qt 默认的编码(cpp源文件的编码需要对应):

QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GBK"));
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));

设置QString默认采用的编码。而究竟采用哪一个,一般来说就是源代码是GBK,就用GBK,源代码是UTF-8就用UTF-8。

还有涉及到路径的问题,那就有一个万能的办法:

QTextCodec *codec = QTextCodec::codecForName("UTF-8");

QTextCodec::setCodecForTr(codec);

QTextCodec::setCodecForLocale(QTextCodec::codecForLocale()); //外部路径,非文件中的代码,windows使用的gb2312,这里就采用了gb2312

    QTextCodec::setCodecForCStrings(QTextCodec::codecForLocale());//

ANSI,UTF8等等这些格式的更多相关文章

  1. unicode,ansi,utf-8,unicode big endian编码的区别

    知乎--http://www.zhihu.com/question/23374078 http://wenku.baidu.com/view/cb9fe505cc17552707220865.html ...

  2. Ansi,UTF8,Unicode,ASCII编码的区别

    Ansi,UTF8,Unicode,ASCII编码的区别 近日需要不同的编码,关于上述编码,一直迷迷糊糊,查了些资料,总算大致了解了, 下面全是从网上搜来的: 1.  ASCII和Ansi编码     ...

  3. 今天被坑了,而且被坑的好爽! 该死的UTF-8 有 BOM 格式编码

    调一个项目,最后无法登录了. 排查到最后发现是cookie无法保存会话ID, 工作两年的经验这时候没用上. 开始一以为是PHP.ini的配置错了. 考虑过域名,浏览器问题. 脚本BUG. 最后最后一步 ...

  4. unicode ansi utf-8 unicode_big_endian编码的区别

      随便说说字符集和编码  快下班时,爱问问题的小朋友Nico又问了一个问题:  "sqlserver里面有char和nchar,那个n据说是指unicode的数据,这个是什么意思.&quo ...

  5. Ansi,UTF8,Unicode,ASCII编码的差别

    近日须要不同的编码,关于上述编码,一直迷迷糊糊,查了些资料,总算大致了解了,以下全是从网上搜来的: 1.  ASCII和Ansi编码    字符内码(charcter code)指的是用来代表字符的内 ...

  6. Ansi,UTF8,Unicode,ASCII编码的区别 ---我看完了 明白了很多

    来自:http://blog.csdn.net/xiongxiao/article/details/3741731 ------------------------------------------ ...

  7. VC++ UTF-8与GBK格式转换

    // 注释:多字节包括GBK和UTF-8 int GBK2UTF8(char *szGbk,char *szUtf8,int Len) { // 先将多字节GBK(CP_ACP或ANSI)转换成宽字符 ...

  8. 批量将文件转换为UTF-8无BOM格式

    最近有一个项目需要迁移,要把文件全部转换成utf8格式的,本来想用python,后来听说PowerShell很是强大,就试着用了一下,果然好用啊! $list = Get-ChildItem .\ - ...

  9. UTF-8, Unicode, GB2312格式串转换之C语言版

    原住址:http://www.cnitblog.com/wujian-IT/archive/2007/12/13/37671.html           /*      author:   wu.j ...

随机推荐

  1. JavaScript Patterns 3.4 Array Literal

    Array Literal Syntax To avoid potential errors when creating dynamic arrays at runtime, it's much sa ...

  2. 【mysql】关于Index Condition Pushdown特性

    ICP简介 Index Condition Pushdown (ICP) is an optimization for the case where MySQL retrieves rows from ...

  3. 谈谈Java的集合组件

    让我们一起谈谈Java的集合组件 我们在使用Java的时候,都会遇到并使用到Java的集合.在这里通过自己的理解和网上的资源对Java的集合方面的使用做一个简单的讲解和总结. Java主要分为3个集合 ...

  4. CSS纯样式实现箭头、对话框等形状

    在使用第三方框架bootstrap的时候,本以为其是图片实现的小箭头,后来使用开发工具查看是用CSS来实现的,现记录如下: 之前都没仔细去观注过其原理,都是拿来使用,在实现小箭头之前需要了解下CSS的 ...

  5. Linux 学习之DNS服务器

    概念: DNS:Domain Name System 域名系统 FQDN:Fully Qualified Domain Name 完整主机名 正向解析:由主机名查IP地址 SOA:开始验证(Start ...

  6. C# Graphic 绘制圆、三角形、椭圆、图片

    在form和panel上可以绘制图形,线段,圆,文字,图形等等. 绘制代码必须放在OnPaint()函数里面,因为窗体刷新的时候,都会调用该函数,重新刷新所绘的图. 示例代码在Panel上绘制图形来简 ...

  7. six month dormancy test

    source data: accountleg    year_month    amount acc1A    2010-01    100 acc1A    2010-02    100 acc1 ...

  8. Java之美[从菜鸟到高手演变]之JVM内存管理及垃圾回收

    很多Java面试的时候,都会问到有关Java垃圾回收的问题,提到垃圾回收肯定要涉及到JVM内存管理机制,Java语言的执行效率一直被C.C++程序员所嘲笑,其实,事实就是这样,Java在执行效率方面确 ...

  9. 【温故而知新-Javascript】比较 undefined 和 null 值

    JavaScript 中有两个特数值: undefined和null,在比较它们的时候需要留心.在读取未赋值的变量或试图读取对象没有的属性时得到的就是 undefined 值. <!DOCTYP ...

  10. OpenCV 之 数字图像

    1  数字图像 数字图像可看作一个数值矩阵, 其中的每个元素代表一个像素点,如下图所示: 2  存储 M行N列图像的存储位数: b = M * N * k   ( L=2k, l ∈ [0, L-1] ...