C语言学习笔记(五)

1.5.4 单词计数

第四个实用程序,用于统计行数、单词数与字符数。这里对单词的定义比较宽松,它是任何其中不包含空格、制表符或换行符的字符序列。

#include <stdio.h>

#define IN     1    /* 在单词内 */
#define OUT  0   /* 在单词外*/

/* 统计输入的行数、单词数与字符数*/
main() {
    int c, nl, nw, nc, state;

    state = OUT;
    nl = nw = nc = 0;
    while ((c = getchar()) != EOF) {
        ++nc;
        if (c == '\n')
            ++nl;
        if (c == ' ' || c == '\n' || c == '\t')
            state = OUT;
        else if (state == OUT) {
            state = IN;
            ++nw;
        }        
    }
    printf("%d %d %d\n", nl, nw, nc);
}

下列语句

nl = nw = nc = 0;

将把其中的3个变量nl、nw与nc都设置为0。运算符 || 代表OR(逻辑或),所以

if (c == ' ' || c == '\n' || c == '\t')

的意义时“如果c是空格,或c是换行符,或c是制表符‘。相应的&&代表AND(逻辑与),它比||高一个优先级。由&&或||连接的表达式由左至右求值,并保证在求值过程中只要能够判断最终的结果为真或假,求值就立即终止。

练习1-11 你准备如何测试单词计数程序?如果程序中存在某种错误,那么什么样的输入最可能发现年这类错误呢?
练习1-12  编写一个程序,以每行一个单词的形式打印其输入。

————————————————————————————————————
练习1-11 其实就是测试用例的编写:
test1:不输入任何字符,直接结束输入(Ctrl+D)。res:0 0 0
test2:输入1个字符,a,按结束。 res:1 1 1
test3:输入2个字符,中间带有空格或制表符,a a,按结束。 res:1 2 3
test4:输入2个字符,中间不带空格,aa,按结束。res:1 1 2
test5:输入2行,第一行输入1个字符,a;第二行输入1个字符,a,按结束。res:2 2 3
test6:输入2行,第一行输入1个字符,a;第二行输入2个字符,中间带有空格或制表符,a a,按结束。res:2 3 5
test7:输入2行,第一行输入1个字符,a;第二行输入2个字符,中间不带空格,aa,按结束。res:2 2 4
test8:输入换行符\n或者制表符\t或者空格,按结束。res:1 0 1


进行上面测试用例测试,会发现test2输出: 0 1 1,与预期不符,后面的基本都是,少一行。这是什么原因呢?是因为程序以换行符\n作为1行的结束,但是如果这一行输入字符了但是没有输入换行符,这一行就统计不上,所以就得在输出时,判断当前行有没有输入,如果有,就要计算当前行。程序修改如下:
#include <stdio.h>

#define IN     1    /* 在单词内 */
#define OUT  0   /* 在单词外*/

/* 统计输入的行数、单词数与字符数*/
main() {
    int c, nl, nw, nc, state, iflag; // iflag表示这一行有没有输入字符

    state = OUT;
    iflag = 0;
    nl = nw = nc = 0;
    while ((c = getchar()) != EOF) {
        iflag = 1; // 只要有一个输入,那么当前行就要计算
        ++nc;
        if (c == '\n') {
            iflag = 0; // 每次换行重置当前行是否输入装态
            ++nl;
        }
        if (c == ' ' || c == '\n' || c == '\t')
            state = OUT;
        else if (state == OUT) {
            state = IN;
            ++nw;
        }        
    }
    if (iflag == 1)
        ++nl;
    
    printf("%d %d %d\n", nl, nw, nc);
}

————————————————————————————————————
练习1-12

#include <stdio.h>

/* 练习1-12  编写一个程序,以每行一个单词的形式打印其输入。*/
main() {
    int c;

    while ((c = getchar()) != EOF) {
        if (c == ' ' || c == '\t' || c =='\n') {
            if(c != '\n')
                putchar('\n');
        } else {
            putchar(c);
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值