wordcount程序要求测出文本中的单词数,字符数和行数。

设计思路:

将文件读入,逐字检测,检测到空格单词数加一,检测到回车行数单词数加一,如果既不是回车也不是空格则说明是字符,字符数加一

编程时发现的问题:

以上思路针对的是正常输入的文本,实际输入时还会出现种种特殊情况。

1.在一行结束时(换行符之前)出现空格,也就是文本后面加一个空格再按回车,这种情况会导致单词数多1。

2.文本结束时没有按下回车,会导致行数和单词数少1。

3.连续出现几个空格,也会导致单词数增多。

解决方案

设置标志数(int blank=0;),该标志数表示当前读取的文件中的字符的前一个字符是否为空格,0表示前一个字符不是空格,1表示是空格。

在读取当前字符时先查看blank的值,如果当前字符是空格时,如果blank==1,则单词数不作改动,如果blank==0,说明这个空格前之一

个单词,单词数加一,同时将blank赋值为1。如果当前字符是换行符,如果blank==1,则单词数不作改动,如果blank==0,说明换行符前

是一个单词,单词数加一。blank赋值为1。如果既不是空格也不是换行符,则说明这是一个真正的字符,字符数加一然后将blank置0。(读取

到下一个字符时,该字符的前一个是一个有意义的字符,blank!=0)。

if (c == ' ' || c == '\t')//blank
{
if (blank == )
{
count[]++;
blank = ;
}
}
else
if (c == '\n' || c == '\r')//enter
{
count[]++;
if (blank == )
count[]++;
blank = ;
}
else//char
{
count[]++;
blank = ;
}

为什么在遇到换行符时将blank置1?

在正常情况下,文本结束一行跳转下一行时,下一行的第一个字符应该是个有意义的字符,blank会被置0,如果下一行的第一个字符是空格,

blank会被赋值为1,也就是说遇到换行符将blank赋值为1这个操作是可有可无的。但是在文件结尾,这个blank的值起到了计数作用。当文件

读到结尾时,判断blank的值,如果在文件结束时,最后一个单词没有接换行符blank=0,单词数要加一。

while (c != EOF)
{ }
if (blank == )
count[]++;
fclose(fp);

如果在文件结尾单词后面有一个换行符,按照前面正常处理,blank赋值为1之后文件关闭,程序结束。

如果在程序的结尾有多个换行符(文件结尾有多个空行),因为检测到换行符blank置1,所以单词数不会增加,解决了文件特殊格式单词书出现异常的问题。

利用标志数blank进行功能拓展

可以将blank的值赋予更多的含义,如果要实现注释检测功能,当前一个字符为'/'时,用blank==2来判断,当前字符为'/'注释开始,检测到换行符注释结束。

当前字符为'*'时注释开始,用blank==3表示前一个字符为'*',当检测到blank==3当前字符为'/'时注释结束。

fgetc的返回值问题

格式:int fgetc(FILE *stream);

  这个函数的返回值,是返回所读取的一个字节。如果读到文件末尾或者读取出错时返回EOF。
  在查找函数用法是发现可以将fgetc的值赋给一个整型变量(int),仔细查了一下fgetc的返回类型
  发现fgetc函数在读到文件末尾时返回EOF,而EOF的本质是一个宏,#define EOF (-1),表示-1。
  这返回值,需要是-1才可以表示文件读到末尾了,那可以char类型表示-1,但是-1在char类型中表示的值为0xff,然而它本身就是一个字节的内容,
如果文件中的一个字节是0xff,难道就认为文件结束,这是不合理的,用int作返回值,就不会出现这个问题,-1用int表示为0xffffffff;而字节值如果
0xff这它返回的int值就会是0x000000ff,这样就可以区别开字节值为0xff和文件结束标识EOF。
  EOF只是为了标识已经读到文件末尾,它并不是一个存储在文件中的字节。所以在判断文件是否读完时不能直接判断(fgetc()==EOF)
而是要赋值之后再进行判断
int c;
c = getc(fp);
while (c != EOF)
{ printf("%c", c);
c = fgetc(fp);
}

程序代码已上传至coding.net

05-07 15:24