C语言报告多少字,一个统计字数的程序

统计字数的程序读取输入的字符并报告其中的单词个数。处理时有可以统计字符个数和行数。来看看这样一个程序包含哪些步骤。

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

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之前所读入的最后一个字符不是换行符,就计为一个不完整行。

最棘手的部分是识别单词。首先,必须明确定义一个单词意味着什么。让我们以一个相对简单的方法将一个单词定义为不包括空白字符(也就是说,没有空格、制表符或换行符)的一系列字符。因此,“glymxck”和r2d2是单词。一个单词以程序首次遇到非空白字符开始,在下一个空白字符出现时结束。检测非空白字符最简单明了的判断表达式是这样的:

c !=  ' ' && c != '\n' && c != '\t' /* 当C不是空白字符时,该表达式为真*/

检测空白字符最简单明了的判断是:

c == ' ' c == '\n' || c == '\t' /*当C是空白字符时,该表达式为真*/

但是使用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时对单词计数。如果在您的系统上可以使用_Bool型变量,可以包含stdboo.h头文件并用bool作为inword的类型,取值分别为ture何false.否则,就使用int类型,取值为0和1.

如果使用布尔型变量,通常的习惯是用变量自身的值作为判断条件。也就是说,用:

if (inword)

来代替:

if (inword == true)

并且用:

if (!inword)

来代替:

if(inword==false)

依据是,如果inword为true,则表达式inword == true 结果为true;而如果inword为false,则该表达式也为false。因此倒不如只用inword作为判断条件。与之类似,!inowrd与表达式inword == false值相同(非真即false,非假即true)。

以下附上完整源码:

#include #include #include

/*如果编译器较老,不支持C99,

则将以上#include 行注释,添加typedef enum{false=0,true=1}bool;*/

#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() && !inword)

{

inword = true;//开始一个新单词

n_words ++;//统计单词

}

if(isspace(c) && inword)

{

inword = false;//到达单词的尾部

}

prev = c;//保存字符值

}

if(prev != '\n')

{

p_lines = 1;

}

printf("characters = %ld,word = %d,lines = %d",

n_chars,n_words,n_lines);

printf("partial lines = %d\n",p_lines);

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值