要对输入例程进行更细粒度的控制,您需要学习使用std::ios_base::iostate 流状态goodbit, eofbit, badbit, and failbit。您可以使用std::basic_ios::rdstate 直接检查状态,也可以使用方便的成员函数.good(), .eof(), .bad() and .fail(),请参阅std::basic_istream。
虽然检查.good() 会告诉您输入良好,但它并不能帮助您从失败的输入或错误条件或EOF 中恢复。为此,您必须单独检查发生的错误情况。
继续我的评论并添加一些细节,您可以执行以下操作(您只需对 a 和 b 执行相同的操作 - 您可以移动到函数或成员函数),例如
#include <iostream>
#include <limits>
int main (void) {
int a, b;
/* get input for a */
while (1) /* loop continually reading input */
{
std::cout << "\nenter an integer for a: ";
if (! (std::cin >> a) ) { /* check stream state */
/* if eof() or bad() break read loop */
if (std::cin.eof() || std::cin.bad()) {
std::cerr << "(user canceled or unreconverable error)\n";
goto unrecoverable;
}
else if (std::cin.fail()) { /* if failbit */
std::cerr << "error: invalid input.\n";
std::cin.clear(); /* clear failbit */
/* extract any characters that remain unread */
std::cin.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
}
}
else { /* on succesful read, just output int and break loop */
std::cout << "integer a: " << a << '\n';
/* extract any characters that remain unread */
std::cin.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
break;
}
}
/* same thing for b */
while (1) /* loop continually reading input */
{
std::cout << "\nenter an integer for b: ";
if (! (std::cin >> b) ) { /* check stream state */
/* if eof() or bad() break read loop */
if (std::cin.eof() || std::cin.bad()) {
std::cerr << "(user canceled or unreconverable error)\n";
break;
}
else if (std::cin.fail()) { /* if failbit */
std::cerr << "error: invalid input.\n";
std::cin.clear(); /* clear failbit */
/* extract any characters that remain unread */
std::cin.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
}
}
else { /* on succesful read, just output int and break loop */
std::cout << "integer b: " << b << '\n';
/* extract any characters that remain unread */
std::cin.ignore(std::numeric_limits<std::streamsize>::max(),
'\n');
break;
}
}
unrecoverable:;
}
注意std::numeric_limits<std::streamsize>::max() 与std::cin.ignore 一起使用以清除stdin 中留下的任何违规字符。 (本质上提取字符的最大流大小,直到找到'\n')所以你下一次输入尝试不会尝试重新读取相同的错误字符并由于相同的原因再次失败 - 通常会导致无限如果输入是在循环中进行的,则循环。
还要注意使用旧的goto 以允许从程序中正常退出,无论用户是否取消a 或b 的输入。
这是一个输入例程,所以在你写完之后——去尝试打破它。如果它坏了,修复它。那是你可以捕捉到大多数极端情况的唯一方法,例如
使用/输出示例
$ ./bin/cin_validate_ab
enter an integer for a: no
error: invalid input.
enter an integer for a: OK
error: invalid input.
enter an integer for a: 5, I entered 5!
integer a: 5
enter an integer for b: again!
error: invalid input.
enter an integer for b: 6
integer b: 6
用户在 Linux 上使用 Ctrl+d(或在 Windows 上使用 Ctrl+z)取消输入。
$ ./bin/cin_validate_ab
enter an integer for a: (user canceled or unreconverable error)
检查一下,如果您有任何问题,请告诉我。