while(!(cin>> x))如何重新提示输入

时间:2015-07-01 23:30:13

标签: c++ iostream

while(!(cin >> ar[i]))
    {
        cin.clear(); // clears bad input
        while(cin.get() != '\n')
            continue;
        cout << "Invalid input, please enter valid scores";
    }

上面的代码来自一个更大的文件。我从我的一本教科书中复制了这段代码,我觉得使用它并不是很舒服,因为我不明白它是如何工作的。

我正在使用它作为处理输入错误的措施。

所以ar是一个空的整数数组,如果我决定输入'k',那么

!(cin >> ar[i]) 

是真的。

从这里我清除输入缓冲区(我认为这是正确的,我希望有人确认或争议这个)。终端然后打印“无效输入...” 现在,如果我只按 Enter 没有任何反应,但不是输入换行符?所以代码不应该读

while(cin.get() == '\n'

2 个答案:

答案 0 :(得分:4)

while(!(cin >> ar[i]))

这会尝试解析cin中的值并将其存储在ar[i]中。默认情况下,>>首先跳过空格,然后查看cin中的字符是否描述了ar[i]类型的合法值。如果找到合法值,那么cin流状态仍然为good,并且其operator bool() const将在给定布尔not / !操作的情况下启动,这样while循环将中断。

如果解析失败,则流状态将设置为以下一个或多个:

  • bad(如果出现一些不可恢复的流错误,例如通过网络连接断开连接的stdin),

  • fail(如果角色没有形成该类型的合法值),或

  • eof(文件结束,&#34;正确&#34;关闭/关闭输入,由UNIX / Linux中的^ D提供,Windows中提供^ Z,以及在echo input | program)中调用程序时的输入结束。

所有上述模式都在&#34; State Functions&#34; here

如果由于上述任何错误条件而输入循环......

{
    cin.clear(); // clears bad input

...这不会清除流中的任何输入数据,但会清除badeoffail状态标志,之后可以进行进一步的输入尝试,虽然处于badeof状态的流可能会在尝试进一步输入时立即重新进入该状态(但并非总是如此 - 某些操作系统可能允许在eof条件之后成功输入std::cin如果用户键入/生成EOF代码,则再次键入实际文本...

    while(cin.get() != '\n')
        continue;

这会尝试从终端读取字符,直到遇到换行符\n。这个想法清楚地清除了可能导致fail条件的其他假定的无法解析的输入。遗憾的是,如果问题出现或成为badeof条件,那么此循环将挂起程序,使刻录的CPU无法使用。

    cout << "Invalid input, please enter valid scores";
}

如果问题只是错误输入的值且没有badeof条件,则cout会提示您进一步输入。

  

现在,如果我按下输入没有任何反应,但是没有输入换行符?

每当外循环执行cin >> ar[i]时,它将跳过空格,包括你输入的任何额外换行符,直到它看到一些输入(可能需要一个完整的换行终止行才能被终端刷新或程序将其提供给程序),或badeof条件。内部的while循环不是为了摆脱空行 - 它试图丢弃带有假定的非数字文本的行。

更正后的代码:

while (!(std::cin >> ar[i]))
{
    if (std::cin.bad() || std::cin.eof())
    {
        std::cerr << "Fatal error on cin while reading numbers\n";
        exit(EXIT_FAILURE);
    }
    std::cin.clear();
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    std::cout << "Invalid input, please enter valid scores\n: ";
}

答案 1 :(得分:3)

整个代码的目标是保持打印错误并请求输入,直到用户输入有效数字,然后继续进入程序。

整个代码包含在......

中的循环
while(!(cin >> ar[i]))
如果 cin 流中的输入无效,

表示循环。由于 ar 是一个整数数组,如果输入不是数字,则输入无效。

cin.clear(); // clears bad input

cin 流遇到无效输入时,程序开始执行循环并继续执行此行代码。由于流遇到无效输入,因此它有一个标志,表示存在错误。正如评论所说,这要求你“明确不好的输入”。基本上这是做什么摆脱这个标志。如果不这样做,该标志将保留在流中,并且程序将在下次使用 cin 流时遇到另一个错误,无论用户输入是否有效。

 while(cin.get() != '\n')
        continue;

当程序从用户那里获取输入时,它接受字符串char,无论输入是什么,但是在 cin 流中留下'\ n'。为了防止错误,下次使用 cin 流时,程序必须摆脱'\ n',以及其他任何隐藏的东西。 cin.get()只从 cin 输入流中读取一个char并返回它。由于此函数的返回值未分配给任何内容,因此所有这些操作都会丢弃已读取的char。如果在流中留下了超过'\ n'的情况,则此循环在处理之前检查读取char的值。这样,循环继续执行,而读取的char不是'\ n'。或者换句话说,它循环直到读取的字符为'\ n'。 continue 唯一能做的就是告诉程序跳过循环的当前迭代的其余部分并开始下一次迭代。在这种情况下,这相当于给循环一个空体。您可以使用 {} 替换 continue; ,并且该程序将执行完全相同的操作。

cout << "Invalid input, please enter valid scores";

该程序清除了 cin 中的标记,并清除了可能遗留下来的 cin 中的所有数据。既然已经处理了无效输入中的所有错误,那么还有一件事要做。是时候通知用户输入无效并请求新输入。如果用户输入更多无效输入,则循环重复。如果用户输入有效输入,程序将继续执行下一行代码。