需要额外的换行符

时间:2013-04-25 07:39:36

标签: c++ error-handling

#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()程序进入无限循环

3 个答案:

答案 0 :(得分:0)

以下评论编辑:

cin.ignore()期待一些输入而忽略它。您应该在if之后的cout << "invalid input \n";语句中移动此行。

答案 1 :(得分: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;

答案 2 :(得分: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;
}

这对我来说似乎更清洁:循环直到你成功,然后做 离开循环后成功输出。 (有可能 值得将清除代码clearignore放入 一个单独的功能。如果您使用>>输入, 你经常需要它。)