c++ 中 while 循环的意外行为
Unexpected behavior of while loop in c++
做了这样的事情:
int main()
{
while (true)
{
std::cout << "Enter a number between one and nine. n";
int oneandnine;
std::cin >> oneandnine;
if (std::cin.fail())
{
std::cin.clear();
std::cin.ignore(100, 'n');
std::cout << "INVALID UNPUT!n";
}else if (oneandnine <= 9 && oneandnine >= 1)
{
break;
}else
{
std::cout << "INVALID UNPUT!n";
}
}
return 0;
}
当输入提供类似这样的456aihdb
时,得到这样的东西:
INVALID UNPUT!
Enter a number between one and nine.
INVALID UNPUT!
Enter a number between one and nine.
为什么它会像这样循环两次? 是因为当456
被丢弃而其余的aihdb
没有被丢弃时,这会导致它再次循环并跳过cin
输入?
它完全符合您的想象。
fail
标志不会立即设置,而是格式化输入运算符将整数456
读入oneandnine
,但不设置fail
标志,因为它是有效的整数值。这导致else
案例执行,因为std::cin.fail()
是假的,oneandnine
不在1
和9
之间。
下一次迭代时,读取无效输入,将设置fail
标志,导致第二个错误输出。
处理验证的一种常见方法是将整行读取到一个字符串中,将该字符串放入std::istringstream
并使用它来尝试解析输入:
if (!std::getline(std::cin, line))
{
// Failure of some kind, could be EOF or something else
// Probably best not to continue in this case
}
std::istringstream iss(line);
if (!(iss >> oneandnine))
{
// Invalid input, report it as such
}
if (oneandnine < 1 || oneandnine > 9)
{
// Invalid number, report it as such
}
// Correct input, continue with program
请注意,上述代码将认为6abc
等输入有效。6
将被提取到oneandnine
中,abc
部分将被静默丢弃。如果不需要,还有其他解析方法(例如std::stoi
或std::strtol
,如果不需要例外(。这样做而不是>>
提取,但上面的其余代码应该没问题。
std::istream
的operator >>
不会整行读取。它会读取直到找到无效字符或空格,如果在无效字符之前找到有效字符,则读取操作将成功,并且无效字符将保留在流中。
在您的示例中,第一次迭代成功读取456
并将aihdb
保留在流中。这将失败您的范围检查,然后第二次迭代尝试读取剩余字符,但由于第一个字符不是数字而失败。
如果要读取整行,请使用std::getline
则将整行解析为一个数字。例如:
#include <iostream>
#include <string>
using std::cout;
int main()
{
while (true)
{
std::cout << "Enter a number between one and nine. n";
std::string line;
std::getline(std::cin, line);
int oneandnine;
size_t pos;
try
{
oneandnine = std::stoi(line, &pos);
}
catch ( std::exception& )
{
oneandnine = -1;
}
if (pos != line.size() || oneandnine > 9 || oneandnine < 1)
{
std::cout << "INVALID INPUT!n";
}
else
{
break;
}
}
return 0;
}
相关文章:
- 如何循环打印顶点结构
- 如何在C++中从两个单独的for循环中添加两个数组
- C++我的数学有什么问题,为什么我的代码不能正确循环
- c++ 中 while 循环的意外行为
- 为什么我在循环提升时得到意外的索引::hana::元组
- 在 winapi 回调函数上返回 FALSE 时出现意外行为(循环被跳过?
- 如果在循环中给cin一个意外的输入,则会自动输入C++换行符作为输入
- C++ 循环意外结束
- 循环间隔意外更改
- For循环内特定行的意外迭代
- C++ 子类和运算符=:无限循环和意外调用
- Arduino UNO在执行更复杂的程序时意外循环Serial
- 当循环意外终止时(C/C++)
- 简单的 C++ for 循环意外输出
- for循环中的意外行为
- 一次执行后,嵌套for循环出现意外/未见的中断:高斯消去
- 使用if循环排序时出现意外结果-糟糕的算法
- 使用循环和函数向映射中插入值时的意外行为
- c++中循环字符时的意外结果
- 循环依赖c意外错误或只是一个糟糕的设计