如何处理错误的数据类型输入

Zik*_*Zik 22 c++ error-handling types input

在C++中,你如何处理错误的输入?就像,如果程序要求一个整数,当你输入一个字符时,它应该能够做某事然后循环重复输入,但是当你需要一个整数时输入一个字符时循环变为无限,反之亦然.

chr*_*ris 44

程序进入无限循环的原因是因为std::cin输入失败而设置了错误的输入标志.要做的是清除该标志并丢弃输入缓冲区中的错误输入.

//executes loop if the input fails (e.g., no characters were read)
while (std::cout << "Enter a number" && !(std::cin >> num)) {
    std::cin.clear(); //clear bad input flag
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); //discard input
    std::cout << "Invalid input; please re-enter.\n";
}
Run Code Online (Sandbox Code Playgroud)

请参阅C++ FAQ以及其他示例,包括在条件中添加最小值和/或最大值.

另一种方法是将输入作为字符串并将其转换为整数std::stoi或其他允许检查转换的方法.

  • @Marvin,`cin >> num`如果用户输入就会失败,当它期待一个int时说'a'.它提供了一个转换运算符,允许它隐式转换为`void*`.如果`cin`处于错误状态,它将返回`NULL`.如果没有,它将返回该对象.然后可以将其转换为bool:如果不是NULL则为true,如果为NULL则为false.然后循环可以使用它来评估它需要的bool表达式. (3认同)
  • @Marvin, `cin.ignore (1000, '\n')` 忽略/丢弃输入缓冲区中的字符,直到丢弃 1000 个字符或遇到换行符(以先到者为准)。这是摆脱线条的好方法。您将在 parashift 示例中看到,他们使用流的最大大小而不是 1000 来考虑最大长度的行。我使用 cin.sync() 是因为在执行此操作时,我希望与用户处于平等地位(尚未阅读下一行),因此我放弃了所有内容。最后,“cin”有一个“operator void *”,因此它不能转换为布尔值。 (2认同)

小智 6

最高投票的答案很好地涵盖了解决方案.

除了这个答案,这可能有助于可视化更好的发展:

int main()

    int input = 1;//set to 1 for illustrative purposes
    bool cinState = false;
    string test = "\0";
    while(input != -1){//enter -1 to exit
        cout << "Please input (a) character(s): ";//input a character here as a test
        cin >> input; //attempting to input a character to an int variable will cause cin to fail
        cout << "input: " << input << endl;//input has changed from 1 to 0
        cinState = cin;//cin is in bad state, returns false
        cout << "cinState: " << cinState << endl;
        cin.clear();//bad state flag cleared
        cinState = cin;//cin now returns true and will input to a variable
        cout << "cinState: " << cinState << endl;
        cout << "Please enter character(s): ";
        cin >> test;//remaining text in buffer is dumped here. cin will not pause if there is any text left in the buffer.
        cout << "test: " << test << endl;
    }
    return 0;    
}
Run Code Online (Sandbox Code Playgroud)

将缓冲区中的文本转储到变量并不是特别有用,但它有助于可视化为什么cin.ignore()是必要的.

我注意到对输入变量的更改也是因为如果你在条件中使用输入变量进行while循环,或者在switch语句中它可能会陷入死锁,或者它可能满足你不期望的条件,这可以更难以调试.