简明现代魔法 -> C/C++ -> C 程序设计:单词计数
C 程序设计:单词计数
2010-02-18
这里的单词定义比较宽松,任何不包括空格、制表符、换行符的连续的字符序列,就叫单词。
下面这段程序虽然短小,但是它可是 UNIX 操作系统中 wc 程序的骨干部分,一个操作系统也是由这么一些小程序架构而成。
#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 记录字符数。
程序的逻辑如下:
- 每输入一个字符,nc 自增;
- 如果字符 c == '\n',换行记录 nl 自增;
- 如果 c 是空格,或者 c 是换行符,或者 c 是制表符,那么状态设为 OUT;
- 如果状态是 OUT,就是说字符序列断开了,那么下一个单词开始,记录单词数 nw 自增;
问题:编写一个程序,以每行一个单词的形式打印其输入。
#include <stdio.h>
#define IN 1
#define OUT 0
/* Print Input One Word Per Line */
main()
{
int c, state;
state = OUT;
while((c = getchar()) != EOF)
{
if(c == ' ' || c == '\n' || c == '\t')
{
if(state == IN)
{
putchar('\n');
state = OUT;
}
}
else if(state == OUT)
{
state = IN;
putchar(c);
}
else
putchar(c);
}
}
程序运行结果如下:

程序的逻辑简单分析如下:
- if(c == ' ' || c == '\n' || c == '\t') 判断变量 c 是否是一个单词分隔符。
- 如果是的话,if(state == IN) 将判断这个单词分隔符是否表示单词结束。如果是的话,就输出一个换行符,并修改变量 state 的值为 OUT,说明在单词外部。
- 如果 c 不是一个单词分隔符,也就是说,它是一个单词,这可以分成2种情况:如果它是单词的第一个字符,那么程序会输出这个字符并修改 state 的值为 IN;如果它是其它字符,则直接输出这个字符就可以了。
