某些测试的输入验证无法按预期工作

时间:2015-08-10 16:41:36

标签: c++ double cin validation

double checkInput() {
    double add;
    cout << "\n" << endl;
    cin >> add;
    if (cin.fail()==true)
    {
        cin.clear();
        cin.ignore(INT_MAX, '\n');
        cout << "Incorrect input"<<endl;
    }
    else 
    {
        return add;
    }
}

我使用这段代码来过滤字符输入,例如“Blarg”,“bat12cat”和类似的输入,其中字符/字母首先出现,但是当我用“1gold”,“0.05cake”等测试时,数字首先出现然后是字母,程序接受所有数字直到第一个字母的实例。

我的理解是,导致问题的是cin.ignore()并允许数字通过。

什么会让像“0.05Cats”这样的输入完全被忽略/跳过? 在线搜索,人们建议使用getline()和stringstream。

谢谢。

2 个答案:

答案 0 :(得分:0)

当您输入1.5dog之类的内容然后使用cin >> some_double; >>时,将提取双倍内容,直到它无法再读取为止。因此some_double获得1.5,dog仍然在流中。这不是故障,因此未设置故障位。由于未设置,因此跳过if语句并返回double值,而其余输入保留在流中,并在下次尝试从流中读取时导致出现问题。我的建议是改变你阅读输入的方式。您可以通过std::string接收输入,然后将其转换为所需类型。然后,如果转换失败,您可以发出信号表明您发生了故障。我会使用类似的东西:

bool read_double(std::istream & is, double & number)
{
    std::string line;
    getline(is, line);
    std::size_t pos = 0;
    double temp = stod(line, &pos);
    if (pos != line.size()) // there is extra content in the streams
        return false;
    number = temp;
    return true;
}

你可以看到它使用 Live Example

答案 1 :(得分:0)

通常,有不止一种方法可以做正确的事情。使用&#34; c ++(11)正则表达式类对象&#34;会帮助你。您可以根据需要编辑正则表达式(例如,通过添加-a,b,c,d,e,f来包含十六进制数字。)

#include <iostream>
using namespace std;
#include <string>
using std::string;
#include <regex>

void main()
{
    string input;
    std::regex reg("[-+]?([0-9]*\.[0-9]+|[0-9]+)");

    cout << "Please enter a double type\n";

    while (cin >> input)
    {
        if (std::regex_match(input, reg))
        {
            std::cout << "Valid input\n";
            break;          
        }

        else
        {
            cout << "Invalid input\n";
            cout << "Please enter a double type\n";
        }

    }

    double do_with = std::stod(input,NULL);

    cout << "the double is : " << do_with << endl;

    cin >> input; // to hold the shell
}