2、wordcnt.c(统计字符数、单词书、行数)
//统计字符数、单词书、行数
#include <stdio.h>
#include <ctype.h>//为isspace()函数提供原型
#include <stdbool.h>//为bool、true、false提供定义
#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("输入要分析的文本 (分号终止 |):\n");
prev = '\n';//回车键赋值给字符prev
while ((c = getchar()) != STOP){
//getchar()函数:在控制台接收字符赋值给c,若字符不是|就为真,如果是就为假
n_chars++;//统计字符数
if(c == '\n'){
//如果c字符==回车键,则开始统计行
n_lines++;//统计行
}
if(!isspace(c) && !inword){//isspace,用于检查参数c是否为空格字符
//如果c字符不为空并且为真,意思就是字符c不是空格的时候则为真
//当inword开始为真的时候,便统计单词
inword = true;//开始一个新的单词
n_words++;//统计单词
}
//如果字符c为空并且inword为假的时候就为真
if(isspace(c) && inword){
inword = false;//达到单词的末尾
prev = c;//保存字符的值
}
}
//当字符prev不等于回车键的时候,便为一行
if(prev != '\n'){
p_lines = 1;
}
printf("字符数 = %ld, 单词数 = %d, 行数 = %d,", n_chars, n_words, n_lines);
printf("不完整的行数 = %d\n", p_lines);
return 0;
}
打印结果:
分析:1、首先进入while循环条件:getchar()函数:在控制台接收字符赋值给c,如果在控制台上输入“|”则跳出while循环,进入循环开始统计字符数。
2、接着进入if判断语句条件是如果字符c等于回车键的时候,则开始统计行。
3、下一条if语句条件是字符c不是空格的时候则为真,当inword为true,开始统计单词数。
4、进入下一条if判断语句条件是如果字符c为空并且inword为假的时候就为真,
这句有点绕说简单点就是当字符为空的时候,将字符c保存在前一个字符上。
你可以想象成当输入完最后一个字符的时候,控制台上字符前面的光标为空,为空的时候将字符c赋值给前一个prev。
5、最后一条if判断语句注意是在while循环体外,当字符prev不等于回车键的时候,便为一行,翻译过来就是回车键不能算作是一行。
上面五条语句都已经逐个分析完毕,最后再总结一下大体思路:首先在控制接收字符输入,当输出“|”就会跳出循环体。然后开始统计在控制台上输入的字符数,(1)如果控制台在接收字符的时候收到“回车键”,则算一行。(2)在字符c不是空格的时候,便开始统计单词数.(3)当字符为空的时候,保存最后一个字符。该段文字用括号括起来均表示在while循环体中的if判断语句,怕看的时候分不清特地用括号括起来,以免混淆。最后一条if判断语句因为不是在循环体内,所以就没括起来!
这段代码是根据C Primer Plus书籍编辑的,说实话本来挺简单的一段代码愣是搞得这么复杂,为此写了一段简单的代码,代码效果和上面一样。
#include <stdio.h>
#include <ctype.h>//isspace
#include <stdbool.h>
#define STOP '|'
int main(void){
char ch,prev;
int words=0;
int chars=0;
int lines=0;
while ((ch = getchar()) != STOP){
chars++;
if(ch == '\n'){
lines++;
}
if(isspace(ch)){
words++;
}
if(isspace(ch)){
prev = ch;
}
}
printf("单词数:%d,字符数:%d,行数:%d.\n",words,chars,lines);
return 0;
}
打印结果: