2013-10-05 177 views
1

我正在学习c并理解这种语言是低级的,在这种情况下缺少异常处理。无限循环scanf函数

我做了一个简单的程序,用户从菜单中选择一些选项。它就是这么简单!

该程序分为几个方法 - 其中一种方法等待用户按一个键 - 一个整数是预期的。然后将这个整数返回到另一个保存开关结构的方法。

按下字符时会出现问题 - 在大多数情况下,会启动else块的无限循环。

您必须选择一个替代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。有在缓冲区,换行符'\n'

使用,而不是使用scanf函数下面的宏剩余characheter 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