C ++ - 首次运行后跳过代码?

时间:2013-12-10 20:33:16

标签: c++ c

我有一个do-while循环,如下所示

do
{
    dimensions = NULL;

    printf("=======================================\nDo you want to multiply in 2 dimensions, or 3?\n\n");

    scanf("%c", &dimensions);

    ... //do stuff

    printf("\nEnter r to repeat, return to terminate\n");
    scanf("%c", &key);
    scanf("%c", &key);
}
while(key == 'r');

在第一次运行时,它执行正常。然而问题是当用户输入'r'并点击返回后再次运行代码时。它将带你到第一个printf(“====等,但不允许用户做任何事情,它会直接回到第二个printf(”\ n输入......

我通过代码看看发生了什么,并且在第二次运行程序时只是跳过scanf(以及所有下面的代码,完全没有理由。最初我认为这是因为'维度'不是设置为不运行以下方法的值 - 但我有,即使是这种情况,程序也会运行方法而不是在没有用户输入的情况下跳过它们。

我错过了什么吗?是scanf(一旦它已被使用,还不足以停止程序吗?

3 个答案:

答案 0 :(得分:1)

您的问题是当您的程序从控制台获取scanf输入时,它会将键盘中的数据读入input buffer,然后将值从缓冲区中取出并放入您提供给scanf的位置。问题是当scanf读取一个字符时,它还会将\n读入缓冲区,然后再次调用时,它会读取放入缓冲区的第二个字符(不要求您输入更多内容 - 因为为什么它会吗?它已经在缓冲区内了。)

所以有两个解决方案:一个 - 在stdin上使用fflush,如:fflush(stdin)。第二步 - 编写一个while循环,从输入缓冲区逐个清除字符:while (getchar() != '\n' );

编辑:如需更多阅读,请参阅How to clear input buffer in C?

答案 1 :(得分:0)

通过思考:“用户输入'r'并点击返回”,然后程序读取'r'并重复。输入缓冲区中还剩下什么?按下两个键,代码只读取第一个。

这也是代码需要两次调用scanf的原因。第一个清除输入缓冲区中的额外字符,第二个读取新字符。

答案 2 :(得分:0)

现在发生了什么

要使缓冲区刷新,您需要输入

r<enter>

点击<enter>刷新缓冲区。所以输入缓冲区现在包含两个字符。

r\n

所以第一个scanf会读r
第二个scanf将显示\n

因此,当您到达时,key的值为\n。测试失败,循环不重复。因此,您应该将第二个scanf()读数删除为密钥。

所以你删除了第二个scanf。现在发生了什么?

用户类型

r<enter>

这使得输入缓冲区具有:

r\n

scanf()将r读入key。循环重复正确。但是当我们回到scanf()时。输入缓冲区在缓冲区中仍然具有\n个字符。因此scanf()会立即读取此值,并且循环应该存在。

你应该怎么解决它。

询问Y / N答案并验证输入是否正确。

std::string line;
std::getline(std::cin, line);
while (line != "Y" && line != "N")
{
    std::cout << "Hey cluts enter a correct value. Y/N\n";
    std::getline(std::cin, line);
}