📄 12.2.8 文本方式和二进制方式.txt
字号:
12.2.8 文本方式和二进制方式
.-l;:;;I'"向文件中写入数据时,一旦遇到"换行"字符 (ASCII码为10),则
会转换为"回车一换行" (ASCII码分别为 13、 10)。在读取文件时,一旦遇到"回车一换行"的组合(连
续的ASCII码为13、 10),则会转换为换行字符(ASCII为10)。因此,上面我们以文本方式读取3个字
节的时候,虽然文件中存放的是4个字节的数据,但在读取时正好遇到 13、 10这个组合,系统会将
它们转换为换行字符: 10,然后读取进来,相t
当于只读取了3个字节的数据。因此,最后一个字节b也被读取进来了。
当按照二进制方式向文件中写入数据时,则会将数据在内存中的存储形式原样输出到文件中。上面
我们以二进制方式写入数据时,可以看到文件中存放的数据就是 10。对于 Windows系统下,换行是
由两个字符组成的,即ASCII码1O(回车符)和 13(换行符), 所以对于单独的一个 10来说,在记事本
中显示时就变成了一个小黑块了。
由于文本方式和二进制方式在读取和写入文件时的差异,所以在写入和读取文件时要保持一致。如
果采用文本方式写入,应采用文本方式读取:如果采用二进制方式写入数据,在读取时也应采用二进
制方式。否则会出现问题。例如位图文件可能有多个13、 10组合,如果以二进制方式读取的话,不
会有问题,但是如果以文本方式读取的话,就会把这些组合转换为换行符: 10.从而导致位图数据的
丢失。不管文本文件,还是二进制文件,如果统一采用二进制方式进行写入和读取,则是不会出错
的。因为这种读取和写入是严格按照一个字节一个字节地进行的。
读者一定要注意文本文件和二进制文件、文本方式和二进制方式之间区别,不要混淆。不管是文本
文件和二进制文件,都可以采用二进制方式或文本方式打开,然后进行写入或读取。但是,对于二
进制文件来说,如果以文本方式读取时,可能会出现一些问题。
这里,为读者出一道在面试中经常出现的题目。具体的题目是:给你一个整数,例如: 98341,将这
个整数保存到文件中,要求在以记事本程序打开该文件时,显示的是: 98341, 结果如图 12.10所示。
当然这个题比较简单,主要考察应试者对文本文件和二进制文件的理解。如果直接将这个整数:
98341写入到文本文件中,然后再打开这个文件能否看到这个整数呢?答案是
不可以的。刚才己经说过,对于文本文件来说,它的每一个字节存放的是可表示为一个字符的 ASCII
代码,如果想在记事本中看到 "98341"这几个字符,实际上看到的是这些字符相应的 ASCII码转换
后的字符,也就是说,在记事本中看到 "98341"是 5个字符,并不是整数: 98341。
文件图 12.10面试题要求的显示结果
我们可以做一试验,直接将 98341作为一个整数写入文本文件,然后以记事本打开该文件,看看结
果如何?首先将 File程序中 OnFileWrite函数己有代码注释起来,然后添加下述如例 12-11所示代
码。
例 12-11
void CFileView: :OnFileWrite()
FILE *pFile=fopen( "3.txt ", "w" );
int i=98341 ;
fwrite(&i , 4, l , pFile) ;
fclose (pFile) ;
上述例 12-11所示代码中,因为一个整数占据 4个字节,所以调用 fwrite函数将整数 i的值写入文
件时,将项的大小设置为 4.这样对整数来说,只需要写入一项就可以了。
运行 File程序,单击【文件操作\写入文件】菜单项,然后在 File程序目录下找到 3.txt文件,并
在记事本中打开该文件,可以发现结果是乱码。然后以二进制的方式打开这个文件,结果如下所示:
000000 25 80 01 00 '.t. . . 可以看到,这时的结果是: 0001 8025 .因为一个整数在内存中占据
四个字节,这是十六进制表示,转换为十进制就是 98341。
注意:对于一个多字节的对象(例如整型对趴在不同的计算机中,其
字节的存储排列顺序是不一样。有两种排列规则:一种称为 little endian.即在存储器中按照从最
低字节到最高字节的顺序存储对象,基于Intel的机器都采用这种规则。正因为采用了 little
endian存储顺序,所以上面的 98341(二进制表示为∞ 018025)在存储时表示为 25800100。另一种
排列规则称为 big endian, 在存储器中按照从最高字节到最低字节的顺序存储对象,也就是和我们
平常的书写习惯一致。
读者一定要记住,文件实际上就是数据在内存中的存储形式在外部存储介质上的另一种存放形式。
当以记事本打开 3.txt这个文件的时候,也就是以文本方式打开该文件时,该
文件中存储的每一个字节的数据都要作为 ASCII码转换为相应的字符,但是它的每7个字节的数据转
换为字符之后又是不可读的,因此看到的就是乱码。
如果对文本文件和二进制文件之间的区别比较了解的话,我们就可以知道,如果想在记事本中打开
文件时能够看到 "98341"这 5个字符的话,则在存储时应该存储 "98341 " 这 5个字符的 ASCII码。
因此可以定义一个 5个字符的数组,对于数字字符来说,字符 "0"的 ASCII码是 48.所以 "9"这个
数字字符的 ASCII码就是: 9+480依次类推。然后在写入文件时,直接写入这个字符数组即可。具体
实现代码如例 12-12所示。
例 12-12
void CFileView::OnFileWrite(}
FILE *pFile=fopen (" 3 . txt" , "w") ;
char ch[51;
ch[Ol=9+48;
ch[11=8+48;
ch[21=3+48;
ch[31=4+48;
ch[41=1+48;
fwrite(ch,工, 5, pFile};
fclose (pFile) ;
,
运行 File程序,单击【文件操作飞写入文件 1菜单工页。然后在记事本中打开新生成的
3.仅t文件,这时可以看到其中的内容为: 98341。
当然,这里也可以采用一种简单的方式实现,直接利用 itoa函数将整数转换为字符串,然后将这个
字符串写入文件即可。具体实现代码如例 12-13所示。
例 12-13
void CFileView::OnFileWrite(}
FILE *pFile=fopen(n3.txt" , "w"};
int i=98341;
char ch[51;
itoa(i , ch, 10);
fwrite(ch, 1 , 5 , pFile};
fclose (pFile) ;
上面介组的这道面试题比较简单,只涉及数字的保存,有些面试题把数字和字符夹杂在一起,并要
求以记事本打开时能看到数字,这时只能利用上面介绍的第一种方法,将这些整数数字转换为 ASCII
字符,然后再写入到文件中。
另一种面试题目是,给定一个宇符串,其中既有数字字符,又有 26个英文字母中的几个字符,让你
判断一下哪些是数字字符。对这种问题的解答,实际上就是判断各字符的
"‘
ASCII码,对于数字字符来说,它们的 Ascn码大于等于 48,小于等于 57,在此范围之内,就是数
字字符。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -