2016-11-11 93 views
1

在文字输入在第一scanf(),第二个不运行。 getchar()无法再次尝试输入。它跳过去输入你想再玩一次吗? (Y/N)?似乎your_choice应该采取的性格和事后检查,但性格实际上正在采取ch。是什么导致它像这样工作以及如何解决问题。我试过重新初始化变量,但不起作用。SCANF不工作无效的输入

#include <stdio.h> 

void choice(int); 

int main() { 
    char ch; 
    int random, your_choice; 

    do { 
     srand(time(NULL)); 
     system("cls"); 
     printf("** 0 is for Rock **\n"); 
     printf("** 1 is for Scissors **\n"); 
     printf("** 2 is for Lizard **\n"); 
     printf("** 3 is for Paper **\n"); 
     printf("** 4 is for Spock **\n"); 

     printf("\nEnter your choice here:"); 
     scanf("%d", &your_choice); 

     random = rand() % 5; //random number between 0 & 4 
     if ((your_choice >= 0) && (your_choice <= 4)) { 
      //choice printer omitted for this post 

      if ((random == ((your_choice + 1) % 5)) || (random == ((your_choice + 2) % 5))) 
       printf("\n\n... and you win!!!\n"); 
      else if ((random == ((your_choice + 3) % 5)) || (random == ((your_choice + 4) % 5))) 
       printf("\n\n... and you lose!!!\n"); 
      else if (random == your_choice) 
       printf("\n\nUnfortunately, it's a tie!\n"); 
     } else 
      printf("\nWell, this is wrong! Try again with a number from 0 to 4!!\n"); 

     printf("\nWould you like to play again? (Y/N)?: "); 
     scanf(" %c", &ch); 

    } while (ch == 'y' || ch == 'Y'); 

    return 0; 
} 
+1

对于初学者,带走你的空间在第二'scanf' – jiveturkey

+2

了'%C'前检查scanf'的'的返回值。如果存在解析错误,则无效输入保留在输入缓冲区中,因此在尝试再次扫描相同数据之前,必须先将其清除。如果忽略'scanf'的返回值并且不对其解析错误做出反应,那么通常会导致程序在无效输入上表现完全出乎意料。 – hyde

+0

@hyde打印时,它给出了选择输入的值。 – nAiN

回答

2

如果用户输入不能被转换为数字的字符,scanf("%d", &your_choice);返回0和your_choice留下未修饰的,所以它是未初始化。行为是未定义的。

您应该测试这一点,并跳过违规输入这样:

if (scanf("%d", &your_choice) != 1) { 
     int c; 
     /* read and ignore the rest of the line */ 
     while ((c = getchar()) != EOF && c != '\n') 
      continue; 
     if (c == EOF) { 
      /* premature end of file */ 
      return 1; 
     } 
     your_choice = -1; 
    } 

说明:

  • scanf()成功返回转换次数。如果用户键入一个数字,它被转换并存储成your_choicescanf()返回1,如果用户输入的东西,不是数字,如AAscanf()离开违规输入在标准输入缓冲器和返回0,最后如果到达文件的结尾(用户类型^ Z在窗户进入或在UNIX^d),scanf()返回EOF

  • 如果输入未转换为数字,我们进入if语句体:在输入与getchar()一时间被消耗一个字节,直到文件的任何一个结束或换行被读取。

  • 如果getchar()返回EOF,我们已经读取了整个输入流,不需要提示用户输入更多的输入,您可能希望在返回错误代码之前输出错误消息。

  • 否则,请将your_choice设置为-1,这是一个无效值,因此代码的读取会提示并提示进一步输入。

阅读并丢弃违规投入是必要的:如果你不这样做,下一个输入的语句scanf(" %c", &ch);会读,而不是响应Would you like to play again? (Y/N)?:提示等待用户输入违规输入的第一个字符。这是你观察到的行为的解释。

+0

你能解释一下这是怎么工作的 – nAiN

+0

究竟是什么'return 1;'做了什么? – nAiN

+0

它从'main'退出并结束程序。返回值可以通过(在Windows中)通过检查错误级别来捕获可能调用程序的批处理文件。 –