我想求数组中每行单词的平均值。
我试图做一个程序,读取单词,直到EOF输入(通过ctrl + z),然后它显示输入的单词数量(由空格或制表符定义的单词)和每个句子的平均单词(由.
或\n
定义的句子)。
这是我的代码,工作得不是很好。有谁知道我该怎么做,至少让平均部分更有效率吗?显示奇怪的数字。
#include <string.h>
#include <stdlib.h>
int main()
{
char words[100]; int count=0, i, line=0, average;
puts("enter words or CTRL + z");
gets(words);
do
{
for (i=0; i<strlen(words); i++)
{
if (words[i]== ' '|| words[i]=='\t' )
{
count = count + 1;
}
else
{
if (words[i]=='\n'||words[i]== '.')
{
line = line + 1;
average = count/line;
}
}
}
}
while (scanf("%99s", words) != EOF);
printf("total words = %d\n", count);
printf("total sentences = %d\n", line);
printf("average = %d\n", average);
return 0;
}
2条答案
按热度按时间1wnzp6jl1#
这是我的代码,工作得不是很好。
所需变更
请勿使用
gets()
使用
fgets()
读取 * 行 *。scanf("%99s", words)
读取 * 行失败*建议
先测试
'\n'
,计数 * 行*使用
isspace()
测试所有空白平均考虑浮点数
只需要 * 在 * 阅读所有数据后。
启用所有编译器警告
可能还有其他问题。
j1dl9f462#
永远不要使用
gets()
。它对你来说是可访问的,只是因为C库提供者更喜欢避免破坏依赖它的遗留程序。首选fgets()
或[f
]scanf
。或者在某些情况下,fread
也可以。您正在将单词计数为单词 * 分隔符 * 的数量。这通常会导致计数太少,因为它实际上忽略了第一个单词。在您的特定情况下,如果句子分隔符没有伴随单词分隔符,它也会错过计数。我建议计算从非单词到单词的转换,其中非单词不仅包括单词分隔符,还包括句子分隔符。这也将解决在一行中出现多个分隔符时错误计数单词的问题。
您的
scanf()
调用将忽略前导空格,并在随后找到的第一个空格处停止阅读。这将完全搞砸你的单词计数多行输入,你的句子计数以及(因为换行符是空格,因此将被忽略)。fgets()
会是更好的选择。你不需要每次遇到一个新行时都更新平均值,如果输入在一行的中间结束,那会给予你错误的结果。您可能应该等到整个输入都被读取,然后计算平均值。
每次测试
i < strlen(words)
时都要重新计算输入字符串的长度。除非你的编译器碰巧为你优化了它,否则它是非常低效的。相反,可以预先计算长度(每行一次),或者测试是否到达字符串终止符(例如,words[i] != '\0'
)。如果在句号之后输入一个换行符,那么句子计数将是错误的(可以说)--它将计数两个句子,一个句子没有单词。你可以考虑发现这一点并加以纠正,但也许评分员会认为你不应该这样做。
if
/else
树的所有条件都是测试同一个对象的特定值,它的效率可能比switch
语句低一点点。IMO,switch
也更容易阅读。你说你想计算每行的平均字数,但实际上你是在计算每个句子的字数。你的说明书上说你要把换行符算作断句,但据我所知,他们没有说相反的话,这不是一个自然的阅读。
你不需要
stdlib.h
来显示你所显示的内容。如果取出strlen()
调用,则也不需要string.h
。但是,您确实需要stdio.h
,并且没有包含它。