2014-11-01 3 views
1
#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, моя программа просто переходит в бесконечный цикл, и частоты не кажутся правильными. Когда я просто добавляю инструкцию печати для ввода одной строки, она отлично работает. Я не знаю, в чем проблема. Кто-нибудь сможет мне помочь?Бесконечная петля при попытке подсчета частот букв

+0

Вы можете объявить «a» с помощью scanf перед циклом while, а затем проверить, не совпадает ли EOF с телом цикла. – wafflesausage

ответ

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) Рассмотрим unsigned против int для подсчета. 5) A 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; 
} 
+0

Итак, что входит в утверждение if? – user3880587

+0

@ user3880587 Простой append 'break;' в 'if()' -> 'if (a == EOF) {for (c = 0; c <26; C++) {if (count [c]! = 0) printf ("% c% f \ n", c + 'a', ((double) count [c])/accum); } перерыв; } ' – chux

0

Бесконечный цикл вызывается этой линии:

while(1) 

Удалите его, если вам это не нужно, или добавить break заявление где-то.

+0

Да, я забыл об этом. Но теперь, когда я добавляю цикл while, я тестировал его, и ввод, который я написал, был «Это круто» и «Что это», он дал мне только буквы для «Это». – user3880587

0

Еще несколько слов, которые помогут описать вашу проблему и решение (как предложено chux).

Первая проблема, с которой вы сталкиваетесь, заключается в том, что у вас нет логики выхода из цикла while(1).

IE У вас есть бесконечный цикл, потому что это то, что вы закодировали.

Несмотря на то, что вы обнаруживаете EOF, вы ничего не делаете: в вашем коде ничего нет: «Теперь, когда у нас есть EOF, нам нужно выйти из этого цикла while(1)».

Это то, что chux предлагает в своем ответе: вот что такое инструкция break: он говорит: «Выйдем из цикла сейчас».

У вас также есть дополнительная проблема, заключающаяся в том, что вы разбираете строку перед проверкой наличия EOF. Если a - EOF, то вы не должны разбирать строку, потому что вы ее не получили.

Таким образом, вы должны изменить свой код, чтобы ваш EOF проверки перед вашей строкой синтаксического анализа, и когда вы закончите печатать строку после обнаружения EOF, вам нужно break.

Смежные вопросы