C ++ Cin忽略非整数?

时间:2017-08-20 19:35:27

标签: c++ while-loop cin

我有一个关于c ++的问题。我一直在寻找答案,并没有找到任何可以解决我的代码的问题。所以我决定问问自己。我的问题是,我制作了这个小程序,它将输出星期几,所以如果用户输入1,它将输出一周的第一天(星期日或星期一,取决于你居住的地方)等等等等。但是,如果用户输入例如8,则程序将输出“请选择1到7之间的数字!” 但是,我的问题是,当用户输入一个字符或随机字时,它将循环“请选择1到7之间的数字!”永远。

    #include <iostream>
#include <Windows.h>
#include <string>
using namespace std;


int main() {

    int input;


    do {
        cin >> input;
        switch (input) {
        case 1:
            cout << "Sunday" << endl;
            break;
        case 2:
            cout << "Monday" << endl;
            break;
        case 3:
            cout << "Tuesday" << endl;
            break;
        case 4:
            cout << "Wednesday" << endl;
            break;
        case 5:
            cout << "Thursday" << endl;
            break;
        case 6:
            cout << "Friday" << endl;
            break;
        case 7:
            cout << "Saturday" << endl;
            break;
        default:
            cout << "Please choose a number between 1 and 7!" << endl; // if user chooses a number not from 1-7 output this. But if input is not an int and for example "a", it will loop this forever.
            break;
        }

    } while (true);


    return 0;
}

2 个答案:

答案 0 :(得分:0)

IO操作设置有关当前流状态的标志。

这些是重要的标志,如果阅读输入你应该关心什么

  • badbit - 在i / o操作上读/写错误
  • failbit - I / O操作上的逻辑错误
  • eofbit - 输入操作时达到文件结尾

如果将一个字符传递给期望int的流(整体传递错误的数据类型,无法将其转换为cin期望的类型),则failbit已设置。

这就是插入错误输入后进入无限循环的原因。 failbit已设置且cin未清除,因此下次阅读操作也会一次又一次失败。

要做的是取消设置failbit并使用ignore丢弃输入缓冲区中的错误输入。

std::cin.clear();      // without params clears flags
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // Clear input buffer

std::cin.fail()将告诉您是否设置了failbit(错误的IO操作)。

int input;
cin >> input;
while (! cin.fail())
{
   // Process data
   cin >> input;
}

std::cin.eof()会告诉您是否设置了eofbit,达到EOF(标准输入时为CTRL + D / + Z)

if (cin.eof())
{
    // End of file (input) reached
    // Terminate reading
}

答案 1 :(得分:0)

声明cin >> input可能会失败,例如如果用户输入了无法转换为整数值的内容,或者流达到EOF(例如标准输入中的CTRL-D或CTRL-Z)。 如果cin >> input失败,则会发生两件事:首先,设置错误状态,指示失败的类型。其次,表达式返回false,表示没有值写入input

所以你应该在继续之前检查cin >> ...的结果。并且,如果您检测到无效输入,则必须在再次读入之前重置错误标志(使用cin.clear()),并且您可能希望跳过无效输入(使用cin.ignore(...))以便避免一次又一次地读取相同(无效)的输入:

int main() {

    int input;
    while (true) {

        while (!(cin >> input)) {

            if (cin.eof()) {
                cout << "user terminated input." << endl;
                return 0;
            }
            cout << "invalid input (not a number); try again." << endl;
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(),'\n');
        }

        // from here on, you may rely that the user has input a number.

        cout << input;

        // ... your code goes here
    }

    return 0 ;
}

请注意,您应该明确允许程序在到达EOF时退出。否则,当您将包含无效内容的文件作为项目的输入传递时,您可能会遇到无限循环(例如,通过myProgram < input.txt)。