我使用Bjarne Stroustrup的编程:C ++中的原理和实践修改了这段代码,试图检查给出的输入是否有效:
#include <iostream>
using namespace std;
int main()
{
cout << "Please enter your first name and age: ";
string first_name = "???";
int age = -1;
cin >> first_name >> age;
while (!cin) {
cin.clear();
cout << "Sorry, can you enter that again? ";
cin >> first_name >> age;
}
cout << "Hello, "<<first_name<<"! (age "<<age<<")\n";
return 0;
}
除了单词"Sorry, can you enter that again? "
被打印两次,第二次输入之前和之后一次打印时,这是按预期工作的。
任何人都知道为什么会发生这种情况?感谢。
答案 0 :(得分:3)
清除失败位是不够的,还必须清除输入缓冲区中的任何剩余字符。此外,代码看起来比必要的更复杂。以下作品:
std::string name;
int age;
std::cout << "Please enter your name & age: ";
while (not (std::cin >> name >> age)) {
std::cout << "Sorry, can you enter that again? ";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
std::cout << "Hello " << name << " (" << age << ")\n";
哦是的,不要忘记刷新输出流,我不认为这会自动完成。
也就是说,标准输入/输出流是 streams ,所以它们实际上并不适合交互式输入。您应该使用适当的库,例如readline
或ncurses
。
为了说明为什么这很重要,想象用户输入“foo42
”并按回车键。你希望程序现在说“对不起,你能再次输入吗?”但事实并非如此。相反,它温顺地等待用户输入第二个令牌。那肯定是不你对可用性的看法。
答案 1 :(得分:1)
这取决于你输入的内容!
输入"Tim 29"
:作品,“你好蒂姆(29)”。
输入"Tim Tom 29"
:工作,重复一次,“你好汤姆(29)”。
输入"Tim Tom Tina 29"
:工作,两次重复,“Hello Tina(29)”。
我假设你正在尝试第三个。第一个失败是Tom
,谁不是数字。重置错误状态很好,但它没有摆脱Tom
。我们仍然需要再次失败的尝试才能消耗他(Tina
失败,此时他不是一个数字)。只有这样,我们才准备好Tina
。