2016-10-01 23 views
-1

我一直用C运行的剪刀石头布程序时得到一个重复循环:意外环(C)

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


int getUserInput(userInput); 
int getComputerInput(cpuInput); 
int pickWinner(int player, int cpu); 


int main() 
{ 

    int playerWins = 0; 
    int compWins = 0; 
    int ties = 0; 

    int userInput; 
    int cpuInput; 
    int userChoice =1; 
    int compChoice; 
    int decision; 

while (userChoice != 4) 
{ 

    compChoice = getComputerInput(); 
    userChoice = getUserInput(userInput); 

    printf("computer chose %d\n", compChoice); //for debugging 
    printf("you chose %d \n", userChoice);//for debugging 

    decision = pickWinner(userChoice, compChoice); 

    if (decision == 1) 
    { 
     playerWins++; 
    } 
    else if (decision == 2) 
    { 
     compWins++; 
    } 
    else if (decision == 3) 
    { 
     ties++; 
    } 


} 
    printf("Final score is: \nPLAYER: %d \nCOMPUTER: %d \n", playerWins, compWins); 






} 

//generates a random number for computer, 1=rock 2= paper 3=scissors 
int getComputerInput (int cpuInput) 
{ 

    srand(time(NULL)); 
    int r = rand() %3 +1; 
    return r; 
} 

//prompts user for character input, then converts input into a number to return back to main 
int getUserInput(userInput) 
{ 
    char playerPick ; 


     printf("Please choose R, P, or S. (Q for quit)\n"); 

     playerPick = getchar(); 



      switch(playerPick) 
      { 

       case 'R' | 'r': 
        printf("Player chose R. \n"); 
        return 1; 
        break; 

       case 'p': 
       case 'P': 
        printf("Player chose P. \n"); 
        return 2; 
        break; 

       case 's': 
       case 'S': 
        printf("Player chose S. \n"); 
        return 3; 
        break; 

       case 'q': 
       case 'Q': 
        printf("player quit"); 
        return 4; 
        break; 

       default: 
        printf("Invalid choice, choose again \n"); 
        break; 

      } 




} 
//method for determining winner 
int pickWinner(int player, int cpu) 
{ 
    if (player ==1 && cpu ==1) 
    { 
     printf("tie\n\n"); 
     return 3; 

    } 

    else if (player==1 && cpu ==2) 
    { 
     printf("you lose, paper beats rock\n\n"); 
     return 2; 
    } 

    else if (player ==1 && cpu ==3) 
    { 
     printf("you win, rock beats scissors\n\n"); 
     return 1; 
    } 

    else if (player ==2 && cpu ==1) 
    { 
     printf("you win, paper beats rock\n\n"); 
     return 1; 
    } 

    else if (player ==2 && cpu ==2) 
    { 
     printf("tie\n\n"); 
     return 3; 
    } 
    else if (player ==2 && cpu ==3) 
    { 
     printf("you lose, scissors beats paper\n\n"); 
     return 2; 
    } 

    else if (player ==3 && cpu ==1) 
    { 
     printf("you lose, rock beats scissors\n\n"); 
     return 2; 
    } 

    else if (player ==3 && cpu ==2) 
    { 
     printf("you win, scissors beat paper\n\n"); 
     return 1; 
    } 

    else if (player ==3 && cpu ==3) 
    { 
     printf("tie\n\n"); 
     return 3; 
    } 
} 

输出:

enter image description here

好像路过零后到getUserInput方法,我不知道为什么。

任何提示正确的方向将非常赞赏。

道歉,如果这篇文章格式不正确。

在此先感谢

+1

'case'R'| 'r':' - >'case'R':case'r':' –

+0

C不支持_methods_。只有_functions_ – Olaf

+0

并且不要发布文字的图像! – Olaf

回答

0

当你进入输入,通过按下回车结束输入。该键实际上作为换行符放入输入队列中。

所以当你读第一个字符时,你会得到输入的字符(例如'r')。但是,输入队列中的下一个字符是换行符,这将是第二次调用getchar会给你的内容。

有办法可以跳过这个。最简单的是简单地做一个额外的getchar调用放弃下一个字符。但是,如果这不是换行符(例如,如果用户输入了多个字母作为输入),那么这将不起作用。

另一种可能的解决方案是使用fgets来读取整行,然后从该行中获取第一个字符。问题是如果你没有提供足够大的缓冲区来存储这条线,你将会遇到和以前一样的问题。

唯一安全的解决方案是将用户的输入作为字符读取。然后在循环中读取,直到获得换行符。您在循环中读取的字符将被丢弃。

也许是这样的功能:

void skip_past_newline(void) 
{ 
    int c; 

    while ((c = getchar()) != '\n' && c != EOF) 
    { 
     // Do nothing 
    } 
} 

然后,只需调用它,你读取用户输入后:

playerPick = getchar(); 
skip_past_newline(); 

请大家注意几件事情与skip_past_newline功能如上所示:

  1. 接收getchar的结果的变量是int变量。这实际上很重要。

  2. 我不仅检查循环中的换行符,还检查了EOF。这表示已使用的按下了文件结束键组合(在Windows控制台窗口中为Ctrl-Z)并且您应该退出程序。这个检查是为什么你需要使变量为int

0

AFAICS,当用户输入一个无效的选择,getUserInput回报没有价值,因为周围的代码中没有循环再问至少有两个问题getUserInput()

  • 。我非常确定,编译器会对此提出警告。
  • 要输入一个值,用户必须输入一个字符和一个换行符。这是第二次读取的字符,它产生输出“无效的选择”。为了防止这种情况,您必须在读取下一个输入字符之前跳过空格。