cout << "Enter the number: ";
int number;
if (cin >> number)
{
// throw away the rest of the line
char c;
while (cin.get(c) && c != '\n')
if (!std::isspace(c))
{
std::cerr << "ERROR unexpected character '" << c << "' found\n";
exit(EXIT_FAILURE);
}
cout << "Enter names: ";
string name;
// keep getting lines until EOF (or "bad" e.g. error reading redirected file)...
while (getline(cin, name))
...use name...
}
else
{
std::cerr << "ERROR reading number\n";
exit(EXIT_FAILURE);
}
在上面的代码中,这一点...
char c;
while (cin.get(c) && c != '\n')
if (!std::isspace(c))
{
std::cerr << "ERROR unexpected character '" << c << "' found\n";
exit(EXIT_FAILURE);
}
...在数字仅包含空格后检查输入行的其余部分。
为什么不直接使用忽略?
这非常冗长,因此ignore
在流之后使用>> x
是一种经常推荐的替代方法,可以将内容丢弃到下一个换行符,但它有丢弃非空白内容的风险,并且这样做会忽略文件中的损坏数据。您可能关心也可能不关心,具体取决于文件的内容是否受信任、避免处理损坏数据的重要性等。
那么什么时候你会使用 clear 和 ignore 呢?
因此,std::cin.clear()
(and std::cin.ignore()
) 不是必需的,但对于删除错误状态很有用。例如,如果您想让用户有很多机会输入有效数字。
int x;
while (std::cout << "Enter a number: " &&
!(std::cin >> x))
{
if (std::cin.eof())
{
std::cerr << "ERROR unexpected EOF\n";
exit(EXIT_FAILURE);
}
std::cin.clear(); // clear bad/fail/eof flags
// have to ignore non-numeric character that caused cin >> x to
// fail or there's no chance of it working next time; for "cin" it's
// common to remove the entire suspect line and re-prompt the user for
// input.
std::cin.ignore(std::numeric_limits<std::streamsize>::max());
}
使用 skipws 或类似的东西不能更简单吗?
另一个简单但半生不熟的替代方案ignore
是在阅读行之前使用std::skipws
跳过任何数量的空格......
if (std::cin >> number >> std::skipws)
{
while (getline(std::cin, name))
...
...但如果它得到像“1E6”这样的输入(例如,一些科学家试图输入 1,000,000,但 C++ 只支持浮点数的表示法)不会接受,你最终会得到number
set to 1
,并E6
读作的第一个值name
。另外,如果您有一个有效数字后跟一个或多个空行,则这些行将被忽略。