最近写了1个小工具,主要实现自动搜索指定路径下所有文本文件内容,并替换指定字符串,记录下几个容易出错误的地方。
1,fread读出来的buffer寄存到string里,如果要搜索指定的字符串,比如“中华人民共和国”,首先要肯定文件的编码格式是甚么?根据文件的编码格式,对目标串进行编码转换后,才能用string.find去进行查找。
而如何判断文件的编码格式呢,windows下文本文件1般有两种字符集,unicode和gbk,根据文件的前3个字节来决定该文件的编码格式,这3个字节是 “EF BB BF”,如果前3个字节为这3个值,就默许为utf8编码的,否则默许为gbk。
题外话:固然上面的判断比较粗略,由于windows下也能够使用utf16来编码存储文件,打开记事本,另存的时候,使用unicode来编码,或unicode big endian来编码。windows的记事本会在文件前面用BOM来存储文件的编码格式
UTF8编码的BOM为 EF BB BF
utf16编码的BOM 为FF FE
utf16 big endian为 FE FF ,
通常uft16也被叫做UCS编码,通常在windows上我们讲unicode编码,就是指utf16编码。也有1些术语称之为宽字符,由于他使用两个字节来存储文字,即使是ascii码,也使用两个字节来存储。
那末有人会问,难道单纯根据前3个字节来判断文件编码格式不会有问题,固然会有问题了,比如你用notepad新建1个文本文件,写入“联通”两个字,然后保存,再次打开,你会发现文件成乱码了。
为啥呢,由于windows记事本把它当作了utf8编码来辨认了,到了这里有人会问,不是说utf8都有BOM头来标识这个是utf8编码的文件么?没错,utf8并没有强迫使用BOM头,有BOM头的utf8文件,也能够转换为utf8无bom编码的格式,可使用notpad++测试下,因此不能notepad不能单纯的依托BOM头来判断是不是是utf8编码的,而要对文件中的数据进行简单的编码分析来肯定,正是这个缘由,才致使辨认出错。
首先来看下utf8来的编码结构,utf8是采取1⑶个字节对字符进行编码,编码字节数和unicode字符集有严格的对应关系。看下面的对应关系表
Unicode 编码集 utf8编码结构
U0001 ― U007E 0XXXXXXX
U0080 ― U07FF和U0000 110XXXXX 10XXXXXX
U0800 ― UFFFF 1110XXXX 10XXXXXX
联通的gbk字符集是“C1 AA CD A8”
C1 AA 对应的2进制: 1100 0001, 1010 1010
CD AB 对应的2进制: 1100 1101, 1010 1000
请注意红色部份,它和UTF8的编码结构完全1致,因此才误将其认为是utf8无BOM编码的文件。可使用notepad++打开来查看这个文件的编码格式
2,在windows下,换行使用的
来换行,也就是 0D 0A,所以使用2进制来查看文件的时候,会看到换行的地方有很多0D 0A,但是如果fopen的时候仅仅使用 “r”标记来读文件,会读不出来0D,必须使用“rb”标记来读,一样在写文件的时候,也要用“wb”来写,才能吧0D写进去。
原文查看:http://www.seanyxie.com/windows%E4%B8%8B%E6%96%87%E4%BB%B6%E7%BC%96%E7%A0%81%E5%92%8C%E8%AF%BB%E5%86%99%E6%B3%A8%E6%84%8F/
上一篇 一些自定义的Lua常用的工具函数