2013-10-05 4 views
1

Я изучаю c и понимаю, что этот язык является низкоуровневым и в этом контексте не хватает обработки исключений.Бесконечная петля scanf-function

Я сделал простую программу, в которой пользователь выбирает некоторые альтернативы из меню. Просто так просто!

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

Проблема возникает при нажатии символа - в большинстве случаев запускается бесконечный цикл else-block.

Вы должны выбрать альтернативный 0 - 2. Пожалуйста, попробуйте еще раз :-)

Вы должны выбрать альтернативный 0 - 2. Пожалуйста, попробуйте еще раз :-)

Вы должны выбрать альтернатива 0 - 2. Пожалуйста, попробуйте еще раз :-)

...... и так далее

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

Любое предложение, как справиться с этой проблемой?

#include <stdio.h> 
#include <stdlib.h> 

void menu(); 
void runSelection(int selection); 
int getSelection(); 
int pause(); 


int main(void) { 

do{ 
    menu(); 
    runSelection(getSelection()); 
}while(pause()); 

return 0; 
} 

int pause() { 
int c; 
printf("\n\nPress enter to continue!"); 
fflush(stdout); 
/* flush inputstream */ 
while((c = getchar()) != '\n' && c != EOF); 
getchar(); 
return 1; 

} 

void menu() { 

puts(" * * * * * * M E N U * * * * * * *"); 
puts("1. Do something 1"); 
puts("2. Do something 2"); 
puts("3. Do something 3"); 
fflush(stdout); 
} 

void runSelection(int selection) { 

switch (selection) { 
    case 0: 
     puts("you pressed 0"); 
     break; 
    case 1: 
     puts("you pressed 1"); 
     break; 
    case 2: 
     puts("you pressed 2"); 
     break; 
} 
} 

int getSelection() { 

int key; 
int true = 0; 
do { 

    scanf("%d", &key); 

    if (key >= 0 && key <=2) { 
     true = 1; 
    } 
    else { 
     puts("You must choose an alternative 0 - 2. Please try again :-)"); 
     fflush(stdout); 
    } 

} while (true == 0); 

return key; 
} 

ответ

2

У вас есть бесконечный цикл, потому что scanf считывает charachter из входного буфера. есть остальные characheter в буфере, которого символ новой строки '\n'

Используйте следующий макрос вместо использования зсапа directelly

#define SCAN_ONEENTRY_WITHCHECK(FORM,X,COND) \ 
do {\ 
    char tmp;\ 
    while(((scanf(" "FORM"%c",X,&tmp)!=2 || !isspace(tmp)) && !scanf("%*[^\n]"))\ 
      || !(COND)) {\ 
     printf("Invalid input, please enter again: ");\ 
    }\ 
} while(0) 


int main() 

{ 
    int decision; 

    printf("Input data, valid choice 1 or 0: "); 
    SCAN_ONEENTRY_WITHCHECK("%d",&decision,(decision==0 || decision==1)); 
    printf("You have entered good input : %d\n", decision); 
} 

Следующая тема содержит объяснения по этому поводу макросов и как использовать его: Common macro to read input data and check its validity

0

Почему вы не удалили отставание '\n' в getSelection как и везде?

Использование:

int c; 
scanf("%d", &key); 
while((c = getchar()) != '\n' && c != EOF); //Add this line 

в getSelection слишком

0

scanf() сломанный функция, используйте fgets() прочитать строку, а затем кормить результат sscanf() вместо этого, я была точно такая же проблема с scanf(), К сожалению, scanf() - очень проблематичная функция для чтения ввода. См. Мой question.

char line[10]; 
    int number; 
    fgets(line, 10, stdin); // read a 10 character line from standard input and store it in line array 
    sscanf(line, "%d", &number); // look for an integer number inside line and store is in number 
Смежные вопросы