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

下面通过实战来分析下:

下面在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. 大家一起和snailren学java-(五)访问控制权限

    “感觉中间断了一天,可是数数好像又没断……(-_^)” 这一天我们来再次细致讨论一下java的访控机制.java的访控机制其实在编程架构上非常实用的,也就是所谓的隐藏具体实现或者封装. 首先看看使用场 ...

  2. redis-集群(cluster)扫盲篇(一)

    什么是redis的集群 按我个人的理解,redis集群就是实现多个redis节点之间进行数据的共享. 集群有什么好处: 将数据自动split到多个节点进行存储. 当集群中的一部分节点失效或者无法进行通 ...

  3. Memcache修改端口

    修改端口 网上很多的说法都无法起作用(像下面这样) D:\.......memcached -p 10000 -d start 现在有两种解决方法 ①直接修改注册表 HKEY_LOCAL_MACHIN ...

  4. PS网页设计教程XXX——在PS中创建一个漫画书主题网页布局

    作为编码者,美工基础是偏弱的.我们可以参考一些成熟的网页PS教程,提高自身的设计能力.套用一句话,“熟读唐诗三百首,不会作诗也会吟”. 本系列的教程来源于网上的PS教程,都是国外的,全英文的.本人尝试 ...

  5. SQLServerDBA十大必备工具---让生活轻松点(转)

    曾经和一些DBA和数据库开发人员交流时,问他们都用过一些什么样的DB方面的工具,大部分人除了SSMS和Profile之外,基本就没有使用过其他工具了: 诚然,SSMS和Profile足够强大,工作的大 ...

  6. 问题解决——在STL的queue中使用自定义类

    本文原创,转载请保证文章的完整性,并显要的注明出处. 本文链接:http://blog.csdn.net/wlsgzl/article/details/38843513 平时很少用STL,就算用,也基 ...

  7. linux命令后台运行

    有两种方式: 1. command & : 后台运行,你关掉终端会停止运行    2. nohup command & : 后台运行,你关掉终端也会继续运行 一. 简介     Lin ...

  8. 利用Windows自带的Certutil查看文件MD5

    当遇到需要对比两个文件是否一致时,可以使用下面的命令来显示文件的MD5, 然后对比两个文件的MD5码. certutil -hashfile <filename> MD5 命令的相关帮助信 ...

  9. "德意志之歌"的历史

    1841年8月, 词作家奥古斯特在当时属于英国的黑尔格兰岛上度假时, 创作了"德意志之歌"的歌词.9月, 这首歌首次出版发行, 曲调则借用了海顿的一首君主颂歌 - "皇帝 ...

  10. 该如何认识ZBrush中的2.5D绘画

    ZBrush不仅对3D行业进行了改革.让艺术家感到无约束自由创作的3D设计,同时它还是一个强大的绘画程序!基于强大的Pixol功能,ZBrush®将数字绘画提升到一个新的层次.如下图所示,插画功能主要 ...