IO流的读取问题及其在文件中的影响

来源:互联网 发布:香港智腾端口 编辑:程序博客网 时间:2024/05/17 01:31

IO流的读取在底层处理上一向有一个问题,遇到换行会导致某些问题,特别是在之后用getchar()来等待输入的人,常常要试验性的用ignore忽略掉一个字符,而fstream继承自iostream,这个问题扩展到文件读取上。就这两天,我需要从文件中每次读取一个字符,就遇到这个问题了。

到底系统是如何处理的呢?

我们先做一个试验:从某文件(假定为A)中每次读取一个字符,同时置一个变量n,每读取一个字符大小加一,每次读取的字符都按uppercase和hex方式输出到屏幕,直到读到eof为止,舍去eof。执行后我们复制命令行下的内容(右键菜单选择选中+右键),黏贴在一个空白文件中,在winhex打开A文件比较一下。

你会发现,所有的0x0D0A(换行)都会只剩下一个半字符0xA,也即两个字节只剩下半个字节。这也就解释了我们要用ignore去忽略一个字符(其实一个换行只剩下一个半字符)。但是这并不能帮我们解决这个问题,换种思路。


能不能通过强制一次只能读取一个字符或通过自己控制文件指针解决呢?经试验,也是无效的。


再换种思路:

再次做个试验:我们把文件每次读取时的tellg(),n和对应字符写入到一个文件(假定为ff)中,这次,我们直接查看ff的内容。

通过比较,我们可以知道,读取时每遇到一个换行,tellg()比上一个多2,也即文件指针后移两个单位,而一般情况只后移一个单位,最终解决方案出来了!


我们就用一个变量记录上一次的tellg(),如果下一次的tellg()比上一次多2,那么我们就忽略此时读取到的字符,手动加入字符0x0D和0x0A,否则则照读取到的处理即可。


最后,一个伙伴给了个建议:判断字符是否为'\n',经试验,成功通过。个人认为,这应该是最好的办法,直观,有效。


至此,本文结束,最后说两点:

(1)文件区段读取注意考虑其中有换行的情况,特别是采用读取长度控制区段的情况要特别注意;

最好有加入eof检查;读取字符也要考虑函数的返回值。

(2)听闻windows api、C api等的IO模型不同,有兴趣的可以去判断一下,以上方法是否适用。

0 0