我正在尝试学习C ++,并且已经陷入了一些我无法理解的NO
行为的rabbithole。这是我的代码:
cin
这里的问题是,当我第一次输入无效输入(例如某些字母字符)时,程序会卡在#include <iostream>
using namespace std;
int main()
{
int num;
// Get valid input
do
{
if (!cin)
{
// Clear error state and flush any garbage input
cin.clear();
cin.ignore(numeric_limits<streamsize>::max());
}
cout << "Please enter a number: ";
cin >> num;
} while (!cin);
// Echo back what we heard
cout << "You entered: " << num << "\n";
cin.get();
}
语句上。我可以继续输入内容(包括换行符),程序永远不会超过该声明。
根据我的理解,这表明如果cin.ignore(numeric_limits<streamsize>::max())
的第一个参数超过缓冲区的当前大小,则任何未来的字符(直到提供的限制)将继续被丢弃。它是否正确?如果正确,我该如何清除输入缓冲区而不影响将来的输入?
注意:出于某种原因,使用cin.ignore
并在cin.ignore(numeric_limits<streamsize>::max(), '\n')
之后添加cin.ignore()
会使代码正常运行。这只是为了澄清我知道这种可能性存在,但我仍然有兴趣了解上面代码中出现的问题(cin >> num
分隔符未指定)。
答案 0 :(得分:1)
您的代码正在清除任何错误标记,然后丢弃其他字符,直到numeric_limits<streamsize>::max()
或EOF
字符的硬限制(您通常可以使用 Ctrl + Z 输入一个字符) )被击中了。因此,正如您所怀疑的那样,它会不断丢弃您的输入。
您的代码的固定版本只能丢弃字符,直到找到换行符
#include <iostream>
#include <limits>
using namespace std;
int main()
{
int num;
// Get valid input
do
{
if (cin.fail())
{
// Clear error state and flush any garbage input
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
cout << "Please enter a number: ";
cin >> num;
} while (cin.fail());
// Echo back what we heard
cout << "You entered: " << num << "\n";
cin.get();
}
可能是更惯用和更紧凑的版本
#include <iostream>
#include <limits>
using namespace std;
int main()
{
int num;
// Get valid input
while( (cout << "Please enter a number: ") && !(cin >> num) )
{
cout << "Invalid number entered" << endl;
// Clear error state and flush any garbage input
cin.clear();
cin.ignore(cin.rdbuf()->in_avail());
}
// Echo back what we heard
cout << "You entered: " << num << "\n";
cin.get();
}
正如您所指出的那样cin.rdbuf()->in_avail()
可能是一个更简单的解决方案,因为它会完全丢弃流中可读取的字符数。