Amo*_*del 4 c++ int iostream infinite-loop while-loop
在C++中,为了处理错误的输入(比如当程序要求输入一个整数但你输入一个字符时)它应该能够做某事然后循环重复输入.
当需要整数时输入字符时,我的循环无限迭代,反之亦然:
#include<iostream>
int main()
{
while (cout << "Enter a number" && !(cin >> num))
{
cin.sync();
cin.clear();
cout << "Invalid input; please re-enter.\n";
}
}
Run Code Online (Sandbox Code Playgroud)
我应该怎么做才能让程序再次提示输入新内容?
如果cin >> num失败,则需要从流中删除无效输入.我建议使用ignore而不是sync完成这个.究其原因,sync是不保证去除剩余的输入所有的标准库的实现.
#include <iostream>
#include <limits>
int main()
{
int num;
while (cout << "Enter a number" && !(cin >> num))
{
cin.clear(); // clear the error
// Remove input up to a new line
cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
cout << "Invalid input; please re-enter.\n";
}
}
Run Code Online (Sandbox Code Playgroud)
上面的示例std::numeric_limits<std::streamsize>::max()用于检索输入缓冲区可以容纳的最大字符数.这允许ignore()删除尽可能多的字符直到新行.它是惯用的C++,并且优于使用可能只是隐藏您当前遇到的问题的幻数.
这种方法效果很好但不处理输入在数字后面包含额外字符的情况.为了处理这些情况,需要稍微改变循环以处理附加验证.一种选择是读取整行cin,将其放入a std::stringstream,从中读取数字,然后进行其他验证.有一个特殊情况可能需要考虑 - 一条线,其中数字后面的唯一字符是空格.幸运的是,标准库提供了流修改器std::skipws,可以轻松处理这种情况.下面的示例显示了如何在没有太多effor的情况下执行此操作
#include <iostream>
#include <sstream>
int main()
{
int num;
for(;;)
{
std::cout << "Enter a number: " << std::flush;
std::string line;
std::getline(std::cin, line); // Read a line from console
std::stringstream text(line); // store in a string stream
char ch = 0;
if(!(text >> num).fail() && (text >> std::skipws >> ch).fail())
{
break;
}
std::cout << "Invalid input; please re-enter.\n";
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
表达式(text >> std::skipws >> ch).fail()将跳过出现在数字后面的所有空格,然后尝试读取单个字符.如果没有可用的字符,则读取将失败,表示用户仅输入了一个数字而没有其他内容.如果我们尝试使用cin它,即使输入有效,也会等待用户输入更多文本.