之前在C语言程序统计一个文件的字符数和 C Primer Plus(5版)第8章编程题1_文件I/O实现1这两篇文章中,如何实现统计一个文件中的字符个数,我使用了重定向技术和文件I/O函数来统计的方法。重定向技术简单,直接调用了系统的能力,所以代码量也不多。使用fseek和ftell函数也很简单,完全使用了这两个函数的自身的能力。本文再使用第三种方法,是文件I/O函数的getc函数来实现文件字符数的统计。 一、题目描述本题是第8章编程题的第一道题,题目如下: 二、题目及思路分析从题述来看,有如下几个关键点: 1.有这么一个文本文件 2.读入文件中的文本 3.统计文件中字符数 4.判断文件的结尾 下面再给出这4步的每一步的解决思路。 1. 有这么一个文本文件 这个好解决。我事先准备好了一个文本文件,文件名是author.txt,里面准备了一些字符,如下: weibo: http://weibo.com/520JDH zhihu: http://zhihu.com/people/520WX CSDN: http://blog.csdn.net/kelehaier 2. 打开文件 这是要解决的第一个技术点。使用文件I/O包中的fopen函数打开文件,最后记得一定要fclose这个文件。 3. 统计文件中字符数 这是要解决的第二个技术点。如果有一种方法,能够逐一地读取每行的每一个字符,并且每读完一个字符,字符计数器就自增1,那么我们的目的就达到了。在文件I/O函数包中, getc函数就可以达到这个目的。getc函数的功能是逐一读取文件中的每一个字符,当然包含每行的结尾的换行符,它需要一个文件指针作为参数。 4. 判断文件的结尾 这是要解决的第三个技术点,即,如何判断getc函数已经读到了文件末尾。在C中,针对不同的系统,统一以一个“EOF”来表示文件的末尾。这个“EOF”如果你到头文件中查看其 定义,会看到可能是一个整数值,比如“-1”。getc()函数遇到文件末尾后就会返回“EOF”。本程序在getc函数达到文件末尾后,打印出EOF,看看在我的编译环境中EOF的定义值 是什么。 三、代码实现根据上述分析,主要代码如下: pFile = fopen("author.txt","r"); 代码以文本模式打开文件,getc函数使用pFile这个文件指针作为参数,从pFile指向的文件中逐一读取字符,在每读取一个字符时,计数器count自增。当文件位置指示器达到文件 末尾时,也就是getc函数读到文件末尾时,while循环退出。此时计数器count的值便是文件中字符的个数。由于此时文件位置指示器指向结尾,在退出while循环后,代码会将EOF对应的值打出。 四、运行结果本程序的运行环境如下: OS:Windows XP sp3 编译器:TDM-GCC 4.9.2 32-bit Release 运行结果如图: 从运行结果来看,统计出的字符数是97,并且打印出的EOF的值为-1.在我的编译环境中,EOF的值被定义为-1.也许在你的编译环境中,EOF的定义值和我不一样。 现在我将代码中的文件打开模式修改下,如下: pFile = fopen("author.txt","rb"); 使用二进制模式打开文件,那么再来运行下,看看结果如何: 比较两种不同的文件打开模式,一个是文本打开模式,一个是二进制打开模式,发现使用getc函数统计出的字符数不一样! 为了解释这种现象,我就拿本例的文本文件的第一行的内容“weibo: http://weibo.com/520JDH” 画个示意图吧,如下: 这个示意图是在Windows上,文件内容的存储方式示意图。可以看到,一行的换行符其实是由两个字符组成的:一个是 ,一个是 。如果以二进制模式打开这个文件,那么,对于 getc来说,它将看到两个字节,一个是“00001101”( 的二进制),一个是“00001010”( 的二进制),因此getc函数在每行末尾会统计到这两个字符。 如果以文本模式打开这个文件,那么C实现会做一个转换,将“ ”两个字符转换成一个字符“ ”,我再画个示意图如下: 此时getc只能看到一个“00001010”( 的二进制),因此在每行的末尾,getc函数只会统计到“ ”这一个字符。因此在最终的统计结果中,以文本模式打开统计的字符数比以二进制模式打开统计的字符数要少两个,少的这两个就是“author.txt”中第一行和第二行末尾的“ ”字符。 由于在linux上,一般而言,一行的结尾只有换行“ ”这一个字符,因此如果运行环境是linux,那么不管是以文本模式打开还是二进制模式打开,统计到的字符数都是99.有条件的朋友可以自行试下。 五、技术点本文给出了一种统计文件字符数的方法,关键技术点是getc函数。如果运行环境是Win的话,要注意文本模式和二进制模式的区别。 六、总结目前为止,为了实现统计一个文件中的字符数的方法,使用了三个不同的技术手段,一个是重定向技术,一个是文件I/O包中的fseek和ftell,最后一个是I/O包中的getc函数。三种方法各有优缺点。朋友们今后需要在自己的项目中实现这一小功能,可以考虑这三种方法。 |
|
来自: 山峰云绕 > 《C语言数据结构描述Windows程序设计》