3

我改编了 Bjarne Stroustrup 的 Programming: Principles and Practice in 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? "被打印两次,一次在第二次输入之前和一次之后。

有谁知道为什么会发生这种情况?谢谢。

4

2 回答 2

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";

哦,是的,别忘了刷新输出流,我认为这不会自动为你完成。

也就是说,标准输入/输出流是,好吧,,所以它们无论如何都不适合交互式输入。您应该为此使用适当的库,例如readlineor ncurses

为了说明为什么这很重要,假设用户输入“<code>foo42”并按回车键。您希望程序现在会说“抱歉,您能再输入一遍吗?” 但事实并非如此。相反,它温顺地等待用户输入第二个令牌。从可用性的角度来看,这肯定不是您所期望的。

于 2012-09-14T10:16:39.197 回答
1

这取决于您输入的内容!

  • 输入"Tim 29":有效,“Hello Tim(29)”。

  • 输入"Tim Tom 29":有效,重复一次,“Hello Tom(29)”。

  • 输入"Tim Tom Tina 29":有效,重复两次,“Hello Tina(29)”。

我假设你正在尝试第三个。第一个失败是Tom,谁不是数字。重置错误状态很好,但它并没有摆脱Tom. 我们仍然需要再一次失败的尝试来消耗他(失败Tina,那时他不是一个数字)。只有这样我们才能准备好Tina

于 2012-09-14T10:11:50.250 回答