尝试计算字母频率时的无限循环

时间:2014-11-01 23:08:03

标签: c loops frequency infinite letter

#include <stdio.h>
#include <string.h>

int main(void)
{
    char string[100];
    int c = 0, count[26] = {0};
    int accum = 0;
    int a;

    while(1)
    {
       a = scanf("%s", string);
       while ( string[c] != '\0' )
       {

           if ( string[c] >= 'a' && string[c] <= 'z' ){
            count[string[c]-'a']++;
            accum++;
           }

           else if (string[c] >= 'A' && string[c] <= 'Z'){
            count[string[c]-'A']++;
            accum++;
           }
            c++;
       }
       if (a == EOF)
       {
           for ( c = 0 ; c < 26 ; c++ )
           {
            if( count[c] != 0 )
                printf( "%c %f\n", c+'a', ((double)count[c])/accum);
           }
       }
    }
   return 0;
}

所以我有一个程序可以计算标准输入中出现的字母频率,直到EOF。但是一旦我达到EOF,我的程序就会进入一个无限循环,频率似乎不正确。当我只是输入一个print语句输入一个字符串时,它工作正常。我真的不知道问题是什么。有人能帮助我吗?

3 个答案:

答案 0 :(得分:2)

if (a == EOF)应该在a = scanf("%s", string);

之后

然后循环中应存在if()条件。

每次循环时都应重置c = 0

while(1) {
   a = scanf("%s", string);
   if (a == EOF) {
     ...
     break;
   }
   c = 0;
   while ( string[c] != '\0' ) {

通过上述更改,您可以确信您的代码运行良好。在较小程度上还有其他需要考虑的事项。 1)scanf("%s",...无界限。 2)应限制输入。 if (a == EOF)也可以在循环后编码。 3)建议循环条件是scanf()==1的肯定肯定。什么是好的循环,而不是在坏的情况下退出。 4)考虑unsignedint进行计数。 5)for()循环而不是while()对增量循环很有用。 6)避免像26这样的幻数。

BTW:你的代码很好地使用了浮点数,A文字和数组{0}初始化。

#include <stdio.h>
#include <string.h>

int main(void) {
  char string[100];
  unsigned count['z' - 'a' + 1] = { 0 };
  unsigned accum = 0;

  while (scanf("%99s", string) == 1) {
    for (int c = 0; string[c]; c++) {
      if (string[c] >= 'a' && string[c] <= 'z') {
        count[string[c] - 'a']++;
        accum++;
      } else if (string[c] >= 'A' && string[c] <= 'Z') {
        count[string[c] - 'A']++;
        accum++;
      }
    }
  }
  for (int c = 'a'; c <= 'z'; c++) {
    if (count[c - 'a'] != 0)
      printf("%c %f\n", c, ((double) count[c - 'a']) / accum);
  }
  return 0;
}

答案 1 :(得分:0)

无限循环是由这一行引起的:

while(1)

如果您不需要,请将其删除,或在某处添加break语句。

答案 2 :(得分:0)

有助于描述您的问题和解决方案的更多单词(由chux提出)。

您遇到的第一个问题是没有逻辑可以退出while(1)循环。

IE你有一个无限循环,因为这是你编码的。

即使您检测到EOF,也不会对此做任何事情:代码中没有任何内容表示&#34;现在我们有EOF,我们需要退出此while(1)循环& #34;

这正是chux在他的回答中所暗示的:这就是break声明的用途:它说&#34;现在突破循环&#34;。

在检查是否有EOF之前,还有一个问题是您要解析字符串。如果aEOF,则您不得解析字符串,因为您没有解析字符串。

因此,您需要重新排列代码,以便在解析字符串之前进行EOF检查,并在检测到EOF后完成字符串打印时,需要break。< / p>