2013-12-15 4 views
3

Пожалуйста, у меня проблема с моей программой. Всякий раз, когда я пытаюсь ввести float, он попадает в бесконечный цикл. Я знаю, что ввод хранится как целое. Как можно запретить пользователю вводить float (как фильтровать вход).Бесконечный цикл при назначении поплавка целому числу

Почему программа попадает в бесконечный цикл, когда вход является поплавком.

Это пример:

#include <stdio.h> 

main() 
{ 
    int i = 0; 
    while(i<10){ 
     system("cls>null"); 
     printf("%d^2 = %d\n", i, i*i); 

     printf("Index: "); 
     scanf("%d", &i); 
    } 
} 
+1

Прочтите руководство по 'scanf'. Убедитесь, что вы обрабатываете * каждый * способ, которым он может себя вести. –

+1

Получите ввод как строку, проанализируйте его на int и проверьте, может ли он быть проанализирован или нет. – bolov

+0

Вот что я имею в виду. Как я могу это сделать? – rullof

ответ

2

Когда вы вызываете scanf, чтобы прочитать номер, но вход содержит что-то несовместимое с спецификатором формата ввода, scanf do не потребляет такой неправильный ввод, оставляя его в буфере. Ваша программа не очищает буфер от несоответствия входа, введя бесконечный цикл: scanf снова пытается прочитать int, видит, что его нет, и выходит без изменения i. Ваша петля видит, что i меньше 10, и снова вызывает scanf.

Чтобы исправить это, проверьте, что scanf вернул один вход. Используйте вход, когда это правильно, или вызвать scanf снова с %*[^\n]\n спецификатором, что означает «чтение до конца строки, и отказаться от ввода»:

if (scanf("%d", &i) != 1) { 
    scanf("%*[^\n]\n"); 
} 

Примечания звездочки - это означает, что потребляется вход должен быть отброшен, а не записываться в переменную.

+0

Как он получает ввод, когда он читает его до конца? это работает как литье? – rullof

+0

Формат '[^ \ n]' format означает ", состоящую из любых символов, кроме новой строки, повторяющихся сколько угодно раз". Asterisk сообщает 'scanf' отбрасывать эту строку. '\ n' в конце удаляет' \ n' из буфера. Поэтому 'scanf ("% * [^ \ n] \ n ");' call удаляет текущую строку из входного буфера, даже не глядя на его содержимое. Кстати, внутри этого 'if (scanf ("% d ", & i)! = 1)' является хорошим местом для добавления 'printf', говорящего пользователю о том, что вход недействителен и что он должен просить ввести другой целочисленное значение. – dasblinkenlight

0
#include <math.h> 
#include <stdio.h> 

int main (void) 
{ 
    int i = 0; 
    float j = 0; 
    while(i<10) 
    { 
     system("cls"); 
     printf("%d^2 = %d\n", i, i*i); 

     printf("Index: "); 
     if (scanf("%f", &j) <= 0 && j-fabs(j) != 0) 
     { 
      printf ("The input is not an interger"); 
     } 
    } 
} 
+0

@dasblinkenligh Ну ... Я думаю, что прочитайте ввод как строку, проверьте, все ли цифры, а затем используйте 'sprintf()' . Решим проблему. Правильно? –

+0

@KevinDongNaiJia Вы должны использовать возвращаемое значение 'scanf'. то есть должен вернуться 1 –

+0

@KevinDongNaiJia Да, это один из способов исправить это. Другой проверяет возвращаемое значение 'scanf', как указано Ed. – dasblinkenlight

2

Лучше использовать fgets() читать полную строку из стандартного ввода и strtol() разобрать его в номер, например:

char buffer[256]; 
char *endp; 
int i; 
while (fgets(buffer, sizeof(buffer), stdin) != NULL) { 
    // buffer now contains one line (including the terminating newline) 
    i = (int)strtol(buffer, &endp, 10); 
    // endp points to the first character after the parsed number: 
    if (endp > buffer && (*endp == 0 || isspace(*endp))) { 
     printf("%d^2 = %d\n", i, i*i); 
    } else { 
     printf("invalid input\n"); 
    } 
} 
Смежные вопросы