2015-11-18 2 views
0

Я пытаюсь увидеть, если пользователь вводит 3 правильных ввода. Если петля не запрашивает ввод снова и снова, пока они не исправят его правильно.Как проверить, работает ли scanf() в C?

#include <stdio.h> 
int main(void) { 

     int num1,num2; 
     char str; 
     int check; 

     printf("Enter : "); 
     check = scanf("%d,%d, %c", &num1, &num2, &str); 

     while (check != 3) { 

       printf("Enter : "); 
       check = scanf("%d,%d, %c", &num1, &num2, &str); 
     } 


} 

Скажем, если я войду в a, 5.4, c, мы получим бесконечный цикл. Почему он дает бесконечный цикл?

+3

Поскольку 'scanf' не использует вход, если он не соответствует. Таким образом, ваш код постоянно пытается разобрать один и тот же ввод (который никогда не будет успешным). – kaylum

+0

вы инициализируете main как 'int main (void)', а затем вы не возвращаете значение из main? Где ваше 'возвращение 0'? – JackVanier

+0

Почему вы не используете функцию 'return' – orvi

ответ

1

Есть гораздо больше способов неправильно использовать scanf в цикле, что собственно из них. Основная проблема (помимо ввода или сопоставлением неудач, которые описаны в странице человека), не в состоянии очистить входной буфер (stdin при чтении из терминала) после неудачной попытки преобразования. (Существует также проблема, что пользователь должен что-то ввести.) Когда пользователь вводит текст и нажимает [Enter], newline ('\n') генерируется и помещается во входной буфер, чтобы отметить конец строки. При вводе a, 5.4, c, 'a' прекрасно, но 5.4 не является int и обработка терпит неудачу:

Если обработка директивы неудачна, то дальнейший ввод не считывается, и Scanf() возвращает.

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

В этой ситуации единственный способ предотвратить неопределенный цикл - это вручную очистить входной буфер после вызова scanf. Что-то простое будет делать:

int c; 
... 
while (...) { 
    scanf (...) 
    while ((c = getchar()) != '\n' && c != EOF) {} 
} 

Это гарантирует, что вы начнете с пустого буфера на следующей итерации.Например:

#include <stdio.h> 

int main (void) { 

    int num1 ,num2, c; 
    char str; 

    while (printf ("\nEnter : ") && 
      scanf (" %d, %d, %c%*c", &num1, &num2, &str) != 3) { 
     printf ("error: invalid input, required: 'int, int, char'\n"); 

     /* empty remaining chars from input buffer */ 
     while ((c = getchar()) != '\n' && c != EOF) {} 
    } 

    printf ("\n num1 : %d\n num2 : %d\n str : %c\n\n", num1, num2, str); 

    return 0; 
} 

Пример использования

$./bin/scanf3 

Enter : a 
error: invalid input, required: 'int, int, char' 

Enter : a, 5.4, c 
error: invalid input, required: 'int, int, char' 

Enter : 10, 25 
error: invalid input, required: 'int, int, char' 

Enter : 10, 25, a 

num1 : 10 
num2 : 25 
str : a 

Примечание: это не защищает от входа пользователя ничего (просто нажав [Enter]), а курсор просто сидит там мигает, как он ждет вход. Это неотъемлемое поведение scanf, часть которого является причиной того, что методы ввода ориентированы на линию методы ввода (fgets или getline) предпочтительны при вводе.

-1

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

Очистите буфер перед чтением нового пользовательского ввода с помощью fflush (stdin).

EDIT: Протестировано в windows VS2013.Sorry У меня нет Linux. Окна и Linux определяют поведение fflush() в различных way.if используется в платформе с Windows:

int main(void) { 

    int num1, num2; 
    char str; 
    int check; 

    printf("Enter : "); 
    check = scanf("%d,%d, %c", &num1, &num2, &str); 

    while (check != 3) { 

////Flush the input buffer //// 

     fflush(stdin); 
     printf("Enter : "); 
     check = scanf("%d,%d, %c", &num1, &num2, &str); 
    } 

}

EDIT: это будет работать на всех платформах.

Другой простой способ потреблять остальные читать построчно

while ((c = getchar()) != '\n' && c != EOF); 

так что теперь

int main(void) { 

    int num1, num2; 
    char str,c; 
    int check; 

    printf("Enter : "); 
    check = scanf("%d,%d, %c", &num1, &num2, &str); 

    while (check != 3) { 

     ////read the remaining char //// 
     while ((c = getchar()) != '\n' && c != EOF); 

     printf("Enter : "); 
     check = scanf("%d,%d, %c", &num1, &num2, &str); 
    } 
} 
+0

этот код по-прежнему генерирует бесконечный цикл. – Pawan

+0

@Pawan Я обновил код – HRG

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