有限制的 cin.ignore 是否继续丢弃新输入?
Does cin.ignore with a limit continue discarding new input?
我正在尝试学习 C++,但由于一些我无法理解的 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 >> num
之后添加 cin.ignore()
可使代码正常工作。这只是为了澄清,我知道存在这种可能性,但我仍然有兴趣了解上面代码中出现的问题(未指定 \n
定界符)。
您的代码正在清除所有错误标志,然后丢弃其他字符,直到达到 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()
可能是一个更简单的解决方案,因为它会完全丢弃流中可供读取的字符数。
我正在尝试学习 C++,但由于一些我无法理解的 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 >> num
之后添加 cin.ignore()
可使代码正常工作。这只是为了澄清,我知道存在这种可能性,但我仍然有兴趣了解上面代码中出现的问题(未指定 \n
定界符)。
您的代码正在清除所有错误标志,然后丢弃其他字符,直到达到 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()
可能是一个更简单的解决方案,因为它会完全丢弃流中可供读取的字符数。