如何阻止整数变量采取双输入(十进制前的数字)和任何其他值?

时间:2016-10-06 04:23:52

标签: c++ string cin stringstream

如果我将任何带有字符的double或整数作为最后一个vabiable e的输入,为什么.fail()不起作用?

我为此问题添加了一些输出图片。

Output sample

代码:

int main() {
    string a,b,line;
    double c;
    int d,e;
    stringstream ss;
    getline(cin,line);
    ss<<line;
    ss>>a>>b>>c>>d>>e;
    cout<<"command: "<<a<<endl<<"arg1: "<<b<<endl<<"arg2: "<<c<<endl<<"arg3: "<<d<<endl<<"arg4: "<<e<<endl;
    if(ss.fail())
        cout<<"Error: invalid command"<<endl;
    else
        cout<<"perfect"<<endl;
    return 0;
}

如何解决此问题?

2 个答案:

答案 0 :(得分:2)

>>一旦找到无法解析为无法解析的数据类型的输入,就会停止读取。输入7.5读入int是一个完全可以接受的7,而.5(不能是int的一部分)留在流中,以便从流中读取下一个读取。如果OP为第三个参数(int d)输入了7.5,则将.5读入第四个参数(int e)将失败。

阿。完全忽略了如何修复部分。

我个人的偏好是以字符串形式读取所有数据并自行解析。在这种情况下,我会使用good ol' strtol,主要是因为我没有因为不良用户输入而抛出异常的想法。错别字发生了。他们经常发生异常。处理它。

所以我们会读到std::string e,而不是int e,然后是......

char * endp; // strtol will point endp to character that ended the parsing. 
             // If that's not the end of the string there was stuff we couldn't parse
errno = 0; // clear the error code so we can catch an overflow error 
           // if the number parsed was too big
long num = std::strtol(e.c_str(), &endp, 10); // parse the string as a decimal number
if (*endp != '\0' || errno == ERANGE)
{
    // handle error. Abort, nag user and repeat, whatever
}
// use num

OP已经补充说,他们不允许使用C库调用。就这样吧。 C++ library equivalent is std::stoi.我对上述例外的咆哮解释了为什么我不喜欢这个选项,但是我们走了!

size_t end; 
int num = std::stoi(e, &end); // parse the string as a decimal number
if (end != e.length())
{
    // handle error. Abort, nag user and repeat, whatever
}
// use num

如果完全无法转换,std::stoi会抛出std::invalid_argument。如果提供的数字太大,则会抛出std::out_of_range,因此要么捕获并处理异常,要么让程序中止。你的电话。

答案 1 :(得分:0)

template< typename From,typename To>
static inline bool superConvert(const From& fromVar,To& toVar)
{
    stringstream ss;
    ss<<fromVar;
    ss>>toVar;
    if(ss.fail())
    {
        return false;
    }
    else
    {
        From tempFrom;
        stringstream ss;
        ss<<toVar;
        ss>>tempFrom;
        if(tempFrom != fromVar)
        {
            return false;
        }
        else
        {
            return true;
        }
    }
}

对于整数,此函数工作正常。由于它经过双重检查,正确的方法是使用stdol,但如果不允许,你可以使用它。

int i;
bool convertSuccess = superConvert<string,int>("25",i);
cerr<<i;