do
{
if (cin.fail())
{
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cin.clear();
}
cout << "Please Enter a Number: ";
cin >> N;
} while (cin.fail());
do
{
if (cin.fail())
{
cin.clear(); // MUST CALL CLEAR BEFORE CALLING IGNORE.
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
cout << "Please Enter a Number: ";
cin >> N;
} while (cin.fail());
1条答案
按热度按时间x6yk4ghg1#
失败后,必须在输入或忽略输入流中的任何字符之前清除
std::cin
。如果
std::cin
处于失败状态,则不能输入或忽略任何字符。调用std::cin.clear()
将重置输入流的failbit
(沿着其eofbit
和badbit
),之后std::cin
不再处于失败状态。只有这样,对std::cin.ignore
的调用才会有任何效果。在本例中,您需要颠倒对
std::cin.ignore
和std::cin.clear
的调用顺序:在输入后而不是之前测试
cin.fail()
在下面的评论中,@雷米勒博为在从
cin
获取输入之后而不是之前测试cin.fail()
提供了一个很好的案例。这更接近我自己编写代码的方式。
然而,如果有一个 * 前提条件 *,
cin.fail()
返回false
,在进入这个循环之前隐式或显式地建立,那么这个“改进”的效果是“没有任何改变”。OP的代码和这个版本的行为都是一样的。这就是为什么我在评论中说,我对OP的编码方式很满意,如果这是他想要的方式的话。
使用函数进行控制台输入
在我自己的工作中,我使用了@Some programmer dude在上面的评论中描述的技术:“把整行读成一串。尝试将字符串转换为整数。如果无效或超出范围,请重试。把它放在一个单独的函数中也是一个好主意。”
此外,我允许用户通过在空白行上按Enter键来取消输入操作。否则,我会一直循环,直到用户正确。
我有以下函数模板的三个重载,这取决于需要什么范围检查选项。
1.不收支票
1.检查
min
1.检查
min
和max
在任何时候,我都不能调用
cin.clear
或cin.ignore
。如果std::getline
失败,则抛出std::runtime_error
。函数
tbx::console::get_number
在输入成功时返回true
,在用户取消时返回false
。输入的数字通过参数n
返回。requires子句中的type_traits确保NumType
是以下之一:char
、signed char
、unsigned char
1.签名或未签名:
short
、int
、long
、long long
float
、double
、long double
此声明用于检查
min
和max
的重载。