2015-09-29 3 views
1

Я относительно новичок в C, но я программировал уже несколько лет.scanf вызывает бесконечный цикл в C

Я пишу программу для колледжа, и я смущен, почему функция scanf ниже не вызывается, что приводит к бесконечному циклу.

Я пробовал иметь свой scanf вне функции, называя его дважды, один раз изнутри, один раз из и несколько других способов. Я читал онлайн, что fflush может помочь, но у него нет

Любые предложения?

// store starting variables 
int players; 

// print title 

printf("*------------------------------------*\n"); 
printf("|         |\n"); 
printf("|    Wheel    |\n"); 
printf("|     of     |\n"); 
printf("|    Fortune    |\n"); 
printf("|         |\n"); 
printf("*------------------------------------*\n"); 
printf("\n\nHow many players are there?: "); 

while(scanf("%d", &players) != 1 && players >= 0) { 
    printf("That isn't a valid number of players. Try again: "); 
    fflush(stdin); 
} 

EDIT JUST ПОНЯЛ Я забыл упомянуть кое-что. Эта программа отлично работает при вводе фактического числа. Я хочу, чтобы это было безопасно, если пользователь вводит что-то, что не является строкой, это не приведет к бесконечной петле программы.

+2

Не 'fflush (STDIN)'. – Olaf

+3

логика выглядит неправильно ... вы имели в виду 'while (scanf ("% d ", & players)! = 1 || players <= 0) {' (цикл, если либо 'scanf()' терпит неудачу, либо нет игроков)? Кроме того, 'fflush (stdin)' не очищает входной поток на всех платформах, поэтому убедитесь, что он работает на вашем, прежде чем полагаться на него. – Dmitri

ответ

2

Вероятно, что нечисловой ввод находится в stdin. Код OP не использует это. Результат: бесконечный цикл.

Лучше использовать fgets().

И все же ОП определяется использовать scanf(), проверять его выход и потреблять нечисловой ввод по мере необходимости.

[редактировать] Коррекция на @Dmitri

int players; 
int count; // Count of fields scanned 
while((count = scanf("%d", &players)) != 1 || players <= 0) { 
    if (count == EOF) { 
    Handle_end_of_file_or_input_error(); 
    return; 

    // non-numeric input 
    } else if (count == 0) { 
    int ch; 
    while (((ch = fgetc(stdin)) != '\n') && (ch != EOF)) { 
     ; // get and toss data until end-of-line 
    } 

    // input out of range 
    } else { 
    ; // Maybe add detailed range prompt 
    } 
    printf("That isn't a valid number of players. Try again: "); 
} 
+0

Я не верю, что существует 100% -ная уверенность в использовании fgets вместо scanf. Единственная проблема с scanf заключается в том, что используется почти всегда неправильно. – Michi

2

Используйте fgets для извлечения ввода как строки и sscanf для преобразования его в число. Это предотвращает ошибки в преобразовании из-за предотвращения чтения из stdin. Вы можете распечатать значения кода возврата scanf и игроков, чтобы узнать, что вы действительно получаете. Вы также должны проверить конец файла, который также вызовет бесконечный цикл, поскольку больше не будет ввода из EOF.

+2

scanf всегда старался делать слишком много и искал слишком много новичков. fgets и sscanf всегда имели лучшее разделение механизмов. – msw

+1

Я сделал это на самом деле. Мой scanf возвращает 0 каждый раз. –

+0

Каков вклад в scanf? 0 означает, что он не соответствует строке форматирования. –

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