非预期的循环(C)

时间:2016-10-01 21:37:27

标签: c loops

在C:

中运行Rock Paper Scissors程序时,我一直在重复循环
#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方法,我无法弄清楚原因。

任何正确方向的提示都会非常受欢迎。

如果此帖子格式不正确,

道歉。

提前致谢

2 个答案:

答案 0 :(得分:0)

输入输入时,按 Enter 键结束输入。该键实际上作为换行符放入输入队列。

因此,当您阅读第一个字符时,您将获得输入的字符(例如'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

  3. 的原因

答案 1 :(得分:0)

AFAICS,getUserInput()

至少存在两个问题
  • 当用户输入无效选项时,getUserInput返回没有值,因为代码周围没有循环再次询问。我很确定,编译器会对此发出警告。
  • 要输入值,用户必须输入字符和换行符。这是第二次读取的字符,它产生输出“无效选择”。为防止这种情况,您必须在读取下一个输入字符之前跳过空格。