我有一个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(一旦它已被使用,还不足以停止程序吗?
答案 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()
读数删除为密钥。
用户类型
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);
}