【问题标题】:C if statements skipped overC if 语句跳过
【发布时间】:2014-02-03 20:09:11
【问题描述】:

我目前正在学习 C,并且正在尝试与某些课程要求的相反。 miniMasterMind 是我发现的一个作业,用户猜测计算机随机生成的数字。我试图对其进行简单的翻转,用户告诉计算机它的猜测对于用户生成的 3 位数字是否正确。

我有一个我认为完全可以工作的程序,除了我的 3 个 if 语句要求用户输入有时不起作用。我看不出有什么原因,但编译后我经常会发现一两个 if 语句只是跳过用户输入。我在每一步之后都添加了 system("pause")'s 以便于查看。

游戏中的每一回合,似乎都会出现一组不同的 if 语句。为什么会这样?

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

int main()
{
    // Initialize variables
    int UCMain = 0;
    int CG1 = -1, CG2 = -1, CG3 = -1;
    int win1 = -2, win2 = -3, win3 = -4;
    char check1 = 'A', check2 = 'B', check3 = 'C';
    int turnCount = 0;


    // Print out start screen
    printf("Welcome to masterMind reversed!  Let's see how this works out!\n\n");

    // Accept user input
    printf("Type in a three digit number for the computer to guess.\n");
    scanf_s("%d", &UCMain, 3);

    const int UC1 = (UCMain / 100) % 10;
    const int UC2 = (UCMain / 10) % 10;
    const int UC3 = UCMain % 10;

    printf("\nTest print, UC1: %d UC2: %d UC3: %d\n", UC1, UC2, UC3);
    system("Pause");

    // Start game loop
    while (turnCount < 10)
    {

        // Random number gen
        srand((int)time(0));

        // 1st number
        if (win1 == UC1)
        {
            CG1 = win1;
        }
        else if (win1 != UC1)
        {
            CG1 = rand() % 10;
        }

        // 2nd number
        if (win2 == UC2)
        {
            CG2 = win2;
        }
        else if (win2 != UC2)
        {
            CG2 = rand() % 10;
            if (CG2 == CG1)
            {
                CG2 = rand() % 10;
            } // End unique check
        }

        //3rd number
        if (win3 == UC3)
        {
            CG3 = win3;
        }
        else if (win3 != UC3)
        {
            CG3 = rand() % 10;
            if (CG3 == CG2 || CG3 == CG1)
            {
                CG3 = rand() % 10;
            } // End unique check
        }
        // End random number generation

        printf("The computer guesses: %d%d%d\n", CG1, CG2, CG3);
        system("Pause");

        // Check if numbers are correct
        if (win1 != UC1)
        {
            printf("Is the first number correct? Y/N\n");
            scanf_s("%c", &check1, 1);
            if (check1 == 'Y')
            {
                win1 = UC1;
            } // 
        }// End 1st check

        system("pause");

        if (win2 != UC2)
        {
            printf("Is the second number correct? Y/N\n");
            scanf_s("%c", &check2, 1);
            if (check2 == 'Y')
            {
                win2 = UC2;
            } // 
        }// End second check

        system("pause");

        if (win3 != UC3)
        {
            printf("Is the third number correct? Y/N\n");
            scanf_s("%c", &check3, 1);
            if (check3 == 'Y')
            {
                win3 = UC3;
            } // 
        }// End third check

        system("pause");

        // Check if game is over
        if (win1 == UC1 && win2 == UC2 && win3 == UC3)
        {
            printf("The computer wins!");
        }

        turnCount++;

    } // End while

    // Win/lose state
    if (turnCount == 10)
    {
        printf("The computer loses!");
    }
}

【问题讨论】:

  • 我认为您应该阅读有关过程编程和重构的内容 =) 当整个代码是一个巨大的逻辑块时,很难理解它并识别特定点并掌握工作流程。顺便说一句,也许您不会消耗整个用户输入,或者消耗太多。超过 50% 的病例有类似症状。
  • 您应该在程序开始时只调用一次srand。并且不要将论点转换为int;它需要一个unsigned int 参数,并且演员阵容可能会把事情搞砸。无论如何,它将被隐式转换。将其更改为 srand(time(NULL)) 并将其放在循环之外(0 有效,但 NULL 恕我直言更清楚)。
  • 电脑获胜后也破。否则,计算机可能会在第 5 回合赢,打印它赢了,再循环 5 次,打印它赢了。然后一旦数到 10,它就会打印出它输了。此外,如果winx == UCx,那么重新分配它是没有意义的。最好跳过if (winx == UCx) 直接转到if (winx != UCx)
  • 同样在假设您确实需要在x == ax != a 时执行操作的情况下,第二个不需要else if,只需else,因为x 是其中之一。

标签: c if-statement random


【解决方案1】:

它并没有真正被跳过: 它正在使用换行符:'\n'

使用前面有空格的scanf:

  scanf(" %c", &b); // this one will work instead

将告诉 scanf 任何留在标准输入上的空白字符(包括换行符 '\n')都应该被忽略。

请阅读有关 scanf 的更多信息here

【讨论】:

    【解决方案2】:

    scanf() 正在读取所有用户输入,包括换行符和回车符。如果用户输入“1”并按下回车,您实际上会得到 2 个(或 3 个,取决于平台)输入字符,一个用于数字,一个或两个用于换行符。当您只打算进行一次时,这将刺激您的循环进行 2 或 3 次迭代。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多