在C ++中,为了处理错误的输入(比如当程序要求输入一个整数但你输入一个字符时)它应该能够做某事然后循环重复输入。
当需要整数时输入字符时,我的循环无限迭代,反之亦然:
#include<iostream>
int main()
{
while (cout << "Enter a number" && !(cin >> num))
{
cin.sync();
cin.clear();
cout << "Invalid input; please re-enter.\n";
}
}
我该怎么办才能让程序再次提示输入新内容?
答案 0 :(得分:5)
如果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";
}
}
上面的示例使用std::numeric_limits<std::streamsize>::max()
用于检索输入缓冲区可以容纳的最大字符数。这允许ignore()
删除尽可能多的字符直到新行。这是惯用的C ++,并且优于使用magic numbers,这可能只是隐藏您当前遇到的问题。
这很有效但不处理输入在数字后面包含额外字符的情况。为了处理这些情况,需要稍微改变循环以处理附加验证。一种选择是从cin
读取整行,将其放入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;
}
表达式(text >> std::skipws >> ch).fail()
将跳过出现在数字后面的所有空格,然后尝试读取单个字符。如果没有可用的字符,则读取将失败,表示用户仅输入了一个数字而没有其他内容。如果我们尝试使用cin
执行此操作,即使输入有效,它也会等待用户输入更多文本。
答案 1 :(得分:2)
使用cin.ignore()
代替cin.sync()
并查看原因from this answer
while (cout << "Enter a number" && !(cin >> num)) {
cin.clear(); // clear error
cin.ignore(100, '\n'); // ignore characters until next '\n' (or at most 100 chars)
cout << "Invalid input; please re-enter.\n";
}
请注意,您可以扩展忽略字符数的范围,最大为
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
答案 2 :(得分:-1)
您可以将输入作为字符串读取,将其转换为整数并验证它。
#include <iostream>
#include <string>
using namespace std;
int main()
{
int number = 0;
string input;
do {
cout << "Enter a number: ";
cin >> input;
number = atoi(input.c_str()); // atoi returns 0 on error..
if (number != 0 || input.compare("0") == 0) // but maybe the user really entered "0".
break;
cout << endl;
cout << "Invalid input; please re-enter.\n";
} while (1);
cout << "You entered " << number << endl;
return 0;
}
示例程序执行:
% ./foo
Enter a number: abc
Invalid input; please re-enter.
Enter a number: 2
You entered 2
% ./foo
Enter a number: 0
You entered 0
..虽然这可能不是最优雅的解决方案。