0
#include <iostream>
using namespace std;
int main()
{
    int a;
    do
    {
        /* First reset the flag and then clean the buffer*/
        cin.ignore();
        cin.clear();
        /* Input the number from the user*/
        cout << "Enter number\n";
        cin >> a;
        /*Diplay appropiate error if the input was wrong*/
        if(cin.fail())
        {
            cout << "invalid input \n";
        }
        /*Display the number if the input was valid*/
        else
        {
            cout << "number entered is : " << a << endl;
        }
    }
    while(cin.fail());  //repeat until the input is correct
    return 0;
}

每次我执行这个程序时,我都必须先输入一个新行,然后再cout<<"Enter number\n";执行。

其背后的原因是什么以及可能的解决方案是什么。

注意:没有cin.ignore()程序进入无限循环

4

3 回答 3

0

你正在做的事情有几个问题。第一个正如 Benoit 所说:cin.ignore()在输出提示之前,您调用得太早了。 cin.ignore()将从输入流中准确提取一个字符(除非输入流失败,或者遇到文件结尾)。

第二个是当你循环时(比如说因为用户输入了"abc"),你在重置错误cin.ignore() 之前调用,所以它是一个空操作。如果用户输入的不是数字,您将永远循环,因为您将卡在错误的输入上。您可能应该将 放在处理错误cin.clear()的分支中。if(当然,这意味着您需要某种标志来测试 do...while,因为当您到达那里时,错误将被清除。或者,您可以clear和 放在ignore循环的顶部,但是在一个if,所以你只做他们,如果cin.fail()。)

第三是你忽略了一个字符。如果用户输入,这将在等待他的输入之前"abc"循环四次(加上新行)。"abc"通常的解决方案是忽略下一个换行符:

cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );

这应该您输入之后完成int(可能无论您是否失败,但由于如果您不失败则退出,那么您是否不这样做并不重要)。

最后,关于风格的两点:询问输入是否成功的普遍方法是将流视为布尔值:

if ( !cin ) {
    //  error...
} else {
    //  OK...
}

//  ...
} while ( !cin );

我并不是说这是一种好的做法(在很多方面,我更喜欢你的风格),但它无处不在,以至于其他任何事情都会让你的代码的读者开始思考,并问你为什么做了不同的事情。

我会将带有提示的输入分离到一个单独的函数中,并编写如下内容:

template <typename T>
std::istream&
inputWithPrompt( std::istream& source, std::string const& prompt, T& dest )
{
    std::cout << prompt;
    source >> dest;
    return source;
}

int
main()
{
    int a;
    while ( !inputWithPrompt( std::cin, "Enter a number:", a ) ) {
        std::cin.clear();
        std::cin.ignore( std::numeric_limits<std::streamsize>::max, '\n' );
        std::cout << "Invalid input" << std::endl;
    }
    std::cout << "Number entered is: " << a << std::endl;
    return 0;
}

这对我来说似乎更干净:循环直到你成功,然后在你离开循环后执行成功的输出。(可能值得将清理代码、 theclear和 theignore放在单独的函数中。如果您输入 using >>,您将经常需要它。)

于 2013-04-25T08:21:36.873 回答
0

编辑以下评论:

cin.ignore()期待一些输入,只是忽略它。您应该将这一行移到后面的if语句中cout << "invalid input \n";

于 2013-04-25T07:48:23.187 回答
0
   cin.ignore();
   cin.clear();
   /* Input the number from the user*/
   cout << "Enter number\n";
   cin >> a;

   /* Input the number from the user*/
   cout << "Enter number\n";

   cin.clear();
   cin.ignore();
   cin >> a;
于 2013-04-25T07:57:06.367 回答