本文介绍如何使用循环和 if 语句来统计输入单词的数量。为此,我们首先要了解一下一个函数的用法,这个函数就是 getchar 。
getchar 是标准库里的一个函数,其函数原型位于标准头文件 stdio.h 中。getchar 可用于读取用户输入的字符,不过每次调用 getchar 都只能读取一个字符。例如:
int ch = getchar();
这个语句读取一个字符,并将其值赋值给 ch。您可能注意到了,我把 ch 声明为 int 型,而不是char 型。这是因为,getchar 的返回值是 int 型的,如果把 ch 声明为 char 型,ch 可能不能正确得到某些字符的值,具体原因我有空会写篇文章解释一下。总之,请各位记住,getchar 的返回值是int 型的,如果想把它的返回值赋值给某个变量,则这个变量一定要声明为 int 型!
当然,我们也可以用 scanf 来读取一个字符。例如:
char c;
scanf("%c", &c);
不过,正如您所见到的,这回我们不必把 c 声明为 int 型,相反,我们应该把 c 声明为 char 型。
因为 getchar 仅用于读取字符,所以其效率比功能全面的 scanf 高。同样,因为 getchar 仅用于读取字符,所以它不需要格式限定符。
下面我们先通过一个简单的程序来熟悉 getchar 的功能:
#include <stdio.h>
int main(void)
{
int ch;
while ( (ch = getchar()) != '\n' )
putchar(ch); /* 输出一个字符 */
putchar(ch); /* 输出 '\n' */
return 0;
}
运行结果:
jlk234u0dlkjds.fds435cv46x84w5312cvx34r69712436Q4FDS-/32SDSD
jlk234u0dlkjds.fds435cv46x84w5312cvx34r69712436Q4FDS-/32SDSD
程序重点:
1. 输入的数据会先被放入缓冲区中,等到按了回车键之后才会被送到我们编写的程序里。
这点我以后会详细讲解。
2. (ch = getchar()) != '\n'
getchar 读取一个字符,然后赋值给 ch,接着 (ch = getchar()) 的值和 '\n' 比较,
如果相等,则退出循环。由于按回车时会产生 '\n',所以该程序只能处理一行数据。注意,
此处的括号必不可少,如果写成 ch = getchar() != '\n',由于 != 的优先级比 = 高,
故这个表达式等同于 ch = (getchar() != '\n')。也就是说,如果不写括号,ch 得到
的值就是 0 或者 1。如果您不知道 (ch = getchar()) 的值是什么,请参考27. 表达式。
3. putchar 是标准函数库中定义的函数,其作用是输出一个字符。putchar 的函数原型位于
stdio.h 中。
如果您能看懂这个程序,而且也学会了 if 语句,那么您已经可以亲自动手写一个程序来统计一行输入中的单词数量了。在往下看之前,请您先试着自行写一个。
/*--------------------------------------------------------------
| 作者: Antigloss @ http://stdcpp.cn @ 蚂蚁的 C/C++ 标准编程
|
| 功能: 统计一行输入中的单词数量
-------------------------------------------------------------*/
#include <stdio.h>
#define IN 1 /* 在单词里 */
#define OUT 0 /* 在单词外 */
int main(void)
{
int ch, wc = 0, state = OUT; /* 初始状态为在单词外 */
while ( (ch = getchar()) != '\n' )
{
if (ch == ' ' || ch == '\t')
{ /* 读到空格或者制表符则表明读完了一个单词 */
state = OUT; /* 故当前状态是在单词外。 */
}
else if (state == OUT)
{ /* 如果读到的不是空格或制表符,并且 state 为 OUT, */
/* 则表明读到了一个新单词 */
state = IN; /* 故当前状态是在单词里。 */
++wc;
}
}
printf("%d\n", wc);
return 0;
}
运行结果:
I love you forever, my dear wife!
7
程序重点:
1. ch == ' ' || ch == '\t'
|| 是逻辑运算符,代表“或者”。只要 ch == ' ' 和 ch == '\t' 这两个子表达式
有一个为真,该表达式就为真;如果这两个子表达式都为假,则该表达式为假。
2. else if (state == OUT)
也许您对这一行感到非常迷惑,不知道是什么意思。其实很简单:
else
{
if (state == OUT)
{ /* 如果读到的不是空格或制表符,并且 state 为 OUT, */
/* 则表明读到了一个新单词 */
state = IN; /* 故当前状态是在单词里。 */
++wc;
}
}
写成这样您是不是马上就看明白了?不过,习惯上,很多人都会采用前一种写法。
参考资料:C Primer 5th Edition
The C Programming Language 2nd Edition
C99 标准
本文版权归 蚂蚁的 C/C++ 标准编程 以及 作者 antigloss 共同所有,转载请注明原作者和出处。谢谢。