【问题标题】:Loop repeating itself?循环重复自己?
【发布时间】:2015-07-20 16:35:02
【问题描述】:

我目前正在尝试自学 C,因为我相信这将是 C++ 和 C# 的一个很好的选择(以及在课程开始之前获得先机)。所以我决定在这里写这个循环:

#include <stdio.h>

int main()
{
    bool continueLoop = true;
    char response;
    printf("ARE YOU READY TO RUMBLE?!?!\n Y/N\n");
    response = getchar();
    int counter = 0;

        do
        {
            counter++;
            if (response == 'Y')
            {
                printf("AWESOME!");
                continueLoop == false;
                return 0;
            }
            else if (response == 'N')
            {
                printf("YOU FAIL!");
                continueLoop == false;
                return 0;
            }
           if (continueLoop == true)
            {
                printf("I do not understand your input!\n");
                printf("Please reinput! Y/N\n");
                response = getchar();
            }
            if(counter == 5)
            {
                printf("Exiting!");
                continueLoop == false;
                goto exit;
            }
        }while (continueLoop == true);

    exit:
        return 0;
}

我的问题如下:为什么如果我输入例如“M”作为我的答案,它会自动循环两次;但是,如果给定适当的条件,则正确终止。

另外,我是否应该将响应转换为单个长度的数组,然后尝试以某种方式比较它,而不是 getchar(),或者应该通过 printf 语句来完成 printf("ARE YOU READY TO RUMBLE?!? \n %s", response);

如果有帮助,我将使用 C-Lion 作为我的 IDE,因为我拒绝在 vi、emacs 或记事本中编写任何代码。

编辑代码

int main()
{


    char response;
    printf("ARE YOU READY TO RUMBLE?!?!\n Y/N\n");
    scanf(" %c", &response);

    int counter = 0;


    while (counter < 5)
    {
        counter++;
        if (response == 'Y')
        {
            printf("AWESOME!");

            return 0;
        }
        else if (response == 'N')
        {
            printf("YOU FAIL!");

            return 0;
        }
        else
        {
            printf("I do not understand your input!\n");
            printf("Please reinput! Y/N\n");
            response = getchar();
        }

    }


    return 0;


}

【问题讨论】:

  • 输入M时按两个键。这就是循环执行两次的原因。当你想要比较两个东西时使用==,当你想要分配两个东西时使用=。还使用goto我们被认为是不好的做法。在这种情况下,您可以将goto 替换为break 。
  • 旁注:while (continueLoop) 就够了。
  • .... 根据 Cool Guy 的评论,第二个键是 Enter 键。
  • getchar() 等待换行,并返回您第一次输入的字母,然后返回换行。也永远不要做while (continueLoop == true)。只需使用while (continueLoop),因为 C 认为所有非零值都为真。
  • @LeeDanielCrocker getchar(3) 不会等待任何事情。是终端设备驱动程序逐行提供输入,因此 stdio 阻塞等待输入,直到输入换行符并且终端驱动程序刷新输入队列。这可以通过禁用ICANON(规范模式)使用tcsetattr(3) 进行更改。但请注意,stdio 在读取和写入终端设备时仍将使用行缓冲输入和输出;这也可以使用setvbuf(3) 更改。

标签: c clion


【解决方案1】:

当您输入M 时,您并不是真的只输入M;您正在输入 M 后跟换行符。所以getchar(3) 会在你第一次调用它时返回M,然后它会在第二次调用时返回\n。因此循环执行了两次。

您可以使用scanf(" %c", &amp;response) 捕获输入并忽略空格(换行符、制表符、空格等)。注意格式字符串中的前导空格;需要强制scanf(3) 跳过空格。

前两个 if 中的这些语句也是无用的:

continueLoop == false;

您将continueLoop 与false 进行比较,然后将结果丢弃(如果您不使用-Wall 进行编译,则应该这样做,因为这很可能会给您一个警告)。

你可能想要赋值而不是比较:

continueLoop = false;

【讨论】:

  • 嗯,没错,没有注意到错误的符号。所以我决定改变它,我也改变了我的 printf 语句如下: printf("ARE YOU READY TO RUMBLE?!?!\n Y/N \n %c", &response); 我仍然面临同样的问题,是我编辑不当吗?
  • @Ageoffan 你不能同时使用printf(3)。 printf(3) 写入输出,scanf(3) 读取输入。将printf(3) 保持原样,在printf(3) 之后,将response = getchar(); 替换为scanf(" %c", &amp;response);。
  • 我明白了,没有注意到它是scanf。所以只是为了确认,我目前是否正确编辑它? 字符响应; printf("你准备好隆隆声了吗?!?!\n Y/N\n"); scanf("%c", &response);
  • 仍然奇怪地重复自己,我想知道我的代码是否实际上是 C++ 而不仅仅是 C,因为其中一个 cmets 提到如果我的代码在没有 #include 的情况下如何工作,那么它实际上是C++。由于 IDE 是 C/C++ IDE,因此我的代码可以正常工作。尽管如此,我仍然不确定为什么会发生这种情况。
  • @Ageoffan 您在循环内的else 中仍然有response = getchar();。您还需要将其替换为 scanf(" %c", &amp;response);,就像您之前所做的那样。
【解决方案2】:

最好使用scanf("%c",&amp;ch); 而不是getchar(),因为它会在您第二次调用时返回'\n'。否则其他代码看起来不错。

我的一位朋友指出 scanf 的相同行为是相同的。那么你可以使用getc

c = getc(stdin);

【讨论】:

  • scanf(3) 使用%c 删除通常的空格跳过。这将产生完全相同的效果。
  • 当你说 scanf(3) 时,是我应该这样写它(我假设不会,因为这会引发错误)还是它需要选择东西的强制位置?
  • @Ageoffan 不,这只是一个符号。 UNIX 联机帮助页分为几个部分;括号中的数字表示scanf 的帮助和描述所在的部分。这意味着您可以使用 man 3 scanf 在手册页的第 3 部分中阅读有关 scanf 的信息(第 3 部分用于库调用)。在scanf的情况下,man scanf和man 3 scanf是等价的,但有时会有与函数同名的命令,因此您可能需要指定您感兴趣的命令/部分。
  • @Ageoffan 因此,在 UNIX 世界中,人们使用括号中的节号来引用函数或命令,以明确他们在说什么。您可以使用man man 查看系统中可用的部分(即阅读man 的手册页)。
【解决方案3】:

您的代码中有几个错误。

首先,如果您想重复N 的次数,请使用for 循环,而不是while。 其次,如果您想提前中断循环,请尝试使用break,而不是布尔值。 最后,将布尔值更改为 false 然后 return 0; 是多余的,因为您要退出该函数。

int main() 
{
    char response;
    int i=0;
    for (i=0; i<5; i++)
    {
        printf("ARE YOU READY TO RUMBLE?!?!\n Y/N\n");
        response = getchar();
        if (response == 'Y' || response == 'y')
        {
            printf("AWESOME!");
            break;
        }
        else if (response == 'N' || response == 'n') 
        {
            printf("YOU FAIL!");
            break;
        }
        else
        {
            printf("I do not understand your input!\n");
        }
    }
    return 0;
}

【讨论】:

  • 这似乎根本无法回答问题。
  • 我很欣赏这段代码,但是出于某种原因,我的编译器说 i++ 是无法访问的代码?我想知道这是否是 C-lion 的问题。
  • 将 int i 从 for 循环中移出,将 i 声明到顶部
猜你喜欢
  • 1970-01-01
  • 2020-06-04
  • 1970-01-01
  • 2019-04-28
  • 1970-01-01
  • 1970-01-01
  • 2021-05-31
  • 2016-04-17
  • 2020-04-03
相关资源
最近更新 更多