用户输入数字+字符时出错 [英] Error when user input numbers + characters

查看:144
本文介绍了用户输入数字+字符时出错的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  #include< iostream> 
using namespace std;

int main()
{
int option;

do
{
cout<<类型随机字符(例如:asdwefef);
cin>>选项;

if(cin.good())//如果数字
{

}
else
{
cout ;& 输入无效! << endl;
cin.clear(); //清除缓冲区
cin.ignore(INT_MAX,'\\\
');
}

} while(option!= 0);

return 0;
}

如何解决?我已经尝试使用以下,但结果是一样的。

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


解决方案

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

一般来说,检查 good()不是评估流有效性的首选方法。 Streams有一个内部布尔运算符,为你做这个。所有你需要做的是将一个布尔表达式中的实际输入操作:

  if(std :: cin>选项){
//成功输入
}
else {
//不成功
}

现在,要检查整个输入是否是数字,最好读入一个字符串,并手动进行解析,因为流不能这是自己的(默认)。或者,要使流自身执行此操作,您可以创建自定义的 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){
//输入完全是数字
}
else {
//输入为不完全数字
}


This is my code which display error when user's input is not numeric. However, when user inputs alphanumberic ( eg: 123abc ), it repeats the error message twice.

#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;
}

How do I solve that? I have tried using the following, but the result is the same.

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

解决方案

Input streams parse characters one by one. For numeric extraction, the stream will continually read characters until it finds one that is non-numeric. This doesn't set std::ios_base::failbit if it successfully wrote characters to its operand already, and if there was no attempt to read the non-numeric character. Thus, std::cin.good() will return true for the first iteration.

Generally, checking good() is not the preferred means of assessing stream validity. Streams have an internal boolean operator that does this for you. All you have to do is enclose the actual input operation in a boolean expression:

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

Now, to check if the entire input is numeric, it would be best to read into a string and do the parsing manually, as streams cannot do this on their own (by default). Alternatively, to make the stream do this itself, you can create a customized std::num_get<char> facet that sets the error mask if it can determine that the input was not entirely numeric. This facet will be installed into the stream's locale; you can uninstall it at any time by changing to the original:

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;
    }
};

Install it into the locale and imbue() the locale into the stream to get the desired behavior:

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
}

这篇关于用户输入数字+字符时出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆