C++-在第一次运行后跳过代码

C++ - Skipping code after first run-through?

本文关键字:代码 运行 第一次 C++-      更新时间:2023-10-16

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

do
{
    dimensions = NULL;
    printf("=======================================nDo you want to multiply in 2 dimensions, or 3?nn");
    scanf("%c", &dimensions);
    ... //do stuff
    printf("nEnter r to repeat, return to terminaten");
    scanf("%c", &key);
    scanf("%c", &key);
}
while(key == 'r');

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

我仔细查看代码,看看发生了什么,在第二次运行时,程序只是毫无理由地跳过scanf(以及所有下面的代码。最初我认为这是因为"dimensions"没有设置为不运行以下方法的值-但我有,即使是这样,程序也会运行这些方法,而不是在没有用户输入的情况下跳过它们。

我是不是错过了什么?scanf(不足以在程序使用后停止它吗?

您的问题是,当您的程序从带有scanf的控制台获得输入时,它会将键盘上的数据读取到input buffer中,然后将值从缓冲区中取出并放入您提供给scanf的位置。问题是,当scanf读取一个字符时,它也会将n读取到缓冲区中,然后在再次被调用时,它会读取放入缓冲区的第二个字符(而不要求您提供更多输入,因为为什么要这样做?它已经在缓冲区中有东西了)。

因此有两种解决方案:一种是在stdin上使用fflush,类似于:fflush(stdin)。第二个-写一个while循环,逐个清除输入缓冲区中的字符:while (getchar() != 'n' );

编辑:有关更多阅读,请参阅如何清除C中的输入缓冲区?

仔细想想:"用户输入‘r’并点击return",然后程序读取‘r’,并重复。输入缓冲区中还剩下什么?按下了两个键,代码只读取第一个键。

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

现在发生了什么

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

r<enter>

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

rn

因此,第一次扫描将读取r
第二次扫描将读取n

因此,当您到达时,key的值为n。测试失败,循环不重复。所以您应该删除第二个scanf()读入键。

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

用户类型

r<enter>

这使得输入缓冲区带有:

rn

scanf()将r读取为key。循环正确重复。但当我们回到scanf()时。输入缓冲器中仍然有n字符。因此scanf()立即读取该值,并且循环按其应有的方式存在。

你应该如何修复它

要求回答是/否,并验证输入是否正确。

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