C Primer Plus 第7章 C控制语句:分支和跳转 7.4 一个统计字数的程序

末鹿安然 提交于 2020-04-11 11:03:17

首先,这个程序应该逐个读取字符,并且应该有些方法判断何时停止;第二,它应该能够识别并统计下列单位:字符、行和单词。下面是伪代码描述:

read a character
while there is more input
    increment character count 
    if a line has been read ,increment line count
    if a word has been read ,increment word count
    read next character

前面已经有输入循环的模型了:

while ((ch=getchar())!=STOP)
{
    ....
}

这里的STOP代表通知输入结束的ch取值。现在我们暂且选择一个在文本中不常见的字符(|)。

现在来考虑一下循环体。因为程序使用getchar()来输入字符,所以可以在每个循环周期通过递增一个计数器的值来统计字符 。为了统计行数,程序可以检查换行符。如果字符 是换行符,程序就递增行数计数器的值。有个问题是如果STOP字符出现在一行的中间该 怎么办?行数计数应不应该增加呢?一种做法是将它作为一个不完整的行统计,也就是说,该行有字符 而没有换行符。可以通过追踪前一个字符来识别这种情况 。如果STOP之前所读入的最后一个字符不是换行符,就计数一个不完整行。

最棘手的部分是识别单词,首先,必须明确定义一个单词意味着什么。让我们以一个相对简单的方法将一个单词定义为不包含空白字符的一系列字符。一个单词以程序首次遇到非空白字符开始,在下一个空白字符出现时结束。使用ctype.h中的isspace( )函数会更简单。如果C是空白字符,isspace(c)为真,如果c不是空白字符!isspace(c)为真。

为了知道一个字符是不是在某单词里,可以在读入一个单词的首字符时把一个标志(命名为inword)设置为1。也可以在此处递增单词的计数。

然后,只要inword保持为1,后续的非空白字符就不标记为一个单词的开始。到出现下一个空白字符时,必须将此标志重置为0,并且程序准备搜索下一个单词。

if c is not whitespace and inword is false
    set inword to true and count the word 
if c is whitespace and inword is true
   set inword to false

这种方法在每个单词开始时将inword设置为1,而在每个单词结束时将其设置为0.仅在该标志从0变为1时对单词计数。

//word.c --统计字符、单词和行
#include <stdio.h>
#include <ctype.h>
#include <stdbool.h>
#define STOP '|'
int main(void)
{
    char c ;    //读入字符
    char prev;  //前一个字符
    long n_chars=0L;  //字符数
    int n_lines=0;    //行数
    int n_words=0;    //单词数
    int p_lines=0;    //不完整的行数
    bool inword=false;  //如果c在一个单词中,则inword等于true

    printf("Enter text to be analyzed(| to terminate): \n");
    prev='\n';    //用于识别完整的行
    while((c=getchar())!=STOP)
    {
        n_chars++;        //统计字符
        if(c=='\n')
            n_lines++;    //统计行数
        if(!isspace(c)&&!inword)
        {
            inword=true;  //开始一个新单词
            n_words++;    //统计单词
        }
        if(isspace(c)&&inword)
            inword=false;  //到达单词尾部
        prev=c;    //保存字字符值
    }
    if(prev!='\n')
        p_lines=1;
    printf("characters=%ld,words=%d,lines=%d,",n_chars,n_words,n_lines);
    printf("partial lines = %d\n",p_lines);
    return 0;
}

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!