用户输入数字 + 字符时出错

Error when user input numbers + characters

本文关键字:出错 字符 输入 数字 用户      更新时间:2023-10-16

这是我的代码,当用户的输入不是数字时显示错误。但是,当用户输入字母数字(例如:123abc(时,它会重复错误消息两次。

#include <iostream>
using namespace std;
int main()
{
int option;
do
{
    cout <<"Type random characters ( E.g : asdwefef ) " ;
    cin >> option;
    if (cin.good()) // If numeric
    {
    }
    else
    {
        cout << "Invalid input!" << endl;
        cin.clear();        // Clear buffer
        cin.ignore( INT_MAX, 'n' );
    }
}while (option != 0);
return 0;
}

我该如何解决这个问题?我尝试使用以下方法,但结果是一样的。

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

输入流逐个解析字符。对于数字提取,流将不断读取字符,直到找到非数字字符。这不会设置std::ios_base::failbit它是否已经成功地将字符写入其操作数,以及是否没有尝试读取非数字字符。因此,std::cin.good() 将为第一次迭代返回true

通常,检查good()不是评估流有效性的首选方法。流有一个内部布尔运算符,可以为你执行此操作。您所要做的就是将实际的输入操作括在一个布尔表达式中:

if (std::cin >> option) {
    // successful input
}
else {
    // unsuccessful
}

现在,要检查整个输入是否为数字,最好读取字符串并手动执行解析,因为流无法自行执行此操作(默认情况下(。或者,若要使流自己执行此操作,可以创建自定义std::num_get<char>方面,如果它可以确定输入不完全是数字,则设置错误掩码。此分面将安装到流的区域设置中;您可以随时通过更改为原始版本来卸载它:

class num_get : public std::num_get<char>
{
public:
    iter_type do_get( iter_type it, iter_type end, std::ios_base& str,
                      std::ios_base::iostate& err, long& v) const
    {
        auto& ctype = std::use_facet<std::ctype<char>>(str.getloc());
        it = std::num_get<char>::do_get(it, end, str, err, v);
        if (it != end && !(err & std::ios_base::failbit)
                      && ctype.is(ctype.alpha, *it))
            err |= std::ios_base::failbit;
        return it;
    }
};

将其安装到区域设置中,并将区域设置imbue()到流中以获取所需的行为:

std::locale original_locale(std::cin.getloc());
std::cin.imbue(std::locale(original_locale, new num_get));
if (std::cin >> option) {
    // input was entirely numeric
}
else {
    // input was not entirely numeric
}