C++ 验证C+中的浮点+;没有专门的图书馆

C++ 验证C+中的浮点+;没有专门的图书馆,c++,floating,C++,Floating,我知道以前有人问过这个问题,但答案并没有解决我的问题,因此我提出了这个问题 我有一个简单的程序来找到三个数字中最大的一个,它应该只接受浮点数。如果输入了字符或字符串,则需要显示错误,用户需要再次输入 我有一个函数来获取有效的浮点输入 float validInput() { float x; cout<< flush; cin >> x; while(cin.fail()) {

我知道以前有人问过这个问题,但答案并没有解决我的问题,因此我提出了这个问题

我有一个简单的程序来找到三个数字中最大的一个,它应该只接受浮点数。如果输入了字符或字符串,则需要显示错误,用户需要再次输入

我有一个函数来获取有效的浮点输入

float validInput()
    {
        float x;
        cout<< flush;
        cin >> x;
        while(cin.fail())
        {
            cin.clear();
            cin.ignore(numeric_limits<streamsize>::max(),'\n');
            cout << "Not a numeric value please enter again\n";
            cin >> x;
        }
        return x;
    }
此方法适用于大多数输入。当我输入一个数字后跟一个字符时,validInput函数会异常失败。在提供此类输入时,它会显示错误消息“不是数值,请再次输入”,但不会接受其他输入,而是将字符前的数值视为输入并存储。我的要求是忽略整个输入并请求新的输入

据我了解

cin.ignore(numeric_limits<streamsize>::max(),'\n');
cin.ignore(数值限制::max(),'\n');
不忽略输入开头输入的数字,但仅清除流中的字符,即使cin.fail()为true

有办法解决这个问题吗?cin可能需要不同的参数。但不确定

提前谢谢

资料来源:

PS:我不能使用任何像boost这样的特殊库。该代码用于实现软件测试的测试用例,因此它需要正确处理任何类型的输入。

将从流中顺序读取,因此如果第一个字符表示有效的数字,它认为这是可以的。如果您想确保您读取的内容确实只是一个数字(后面没有其他字符),一个选项是使用将读取为,然后使用(C++11)将字符串转换为浮点。后者将指向无法转换的第一个字符位置的指针作为第二个参数。如果该位置小于字符串的长度,则行中包含的不仅仅是数字,因此输入无效

例如:

#include <iostream>

int main()
{
    float x;
    std::size_t pos;
    std::string str;
    while (std::getline(std::cin, str))
    {
        try
        {
            x = std::stof(str, &pos);
        }
        catch(...)
        {
            std::cout << "Not a numeric value please enter again\n";
            continue;
        }
        if(pos != str.length())
        {
            std::cout << "Not a numeric value please enter again\n";
            continue;
        }
        break;
    }
    std::cout << x;
}
#包括
int main()
{
浮动x;
标准:尺寸和位置;
std::字符串str;
while(std::getline(std::cin,str))
{
尝试
{
x=std::stof(str和pos);
}
捕获(…)
{

std::cout您可能想看看实际发生了什么,因为这种行为一点也不奇怪:当您在一行上输入一个浮点数,后跟一个非数字时,浮点值被提取出来就可以了。
validInput()的失败案例
函数是而不是命中-通过该调用!但是,由于在再次调用函数时存在无法解析为浮点数的内容,因此第二次调用会触发失败

通过在
validInput()
调用之间添加输出,您可以看到这确实是一种行为。通过这种方式,您可以判断哪些调用实际产生了错误。在没有错误时存储值是预期行为

您可以通过读取一行并验证是否可以从该行读取,以及该行上是否只有空格,来确保该行不包含无效输入。例如:

float validInput()
{
    float x;
    // cout<< flush; There is *NO* reason to flush cout: it is flushed when using cin
    for (std::string line; std::getline(std::cin, line); ) {
        std::istringstream lin(line);
        if (lin >> x && (lin >> std::ws).eof()) {
            break;
        }
        cout << "Not a numeric value please enter again\n";
    }
    throw std::runtime_error("reached end of input before getting a valid value!");
    return x;
}
float validInput()
{
浮动x;
//cout>x&(lin>>std::ws.eof()){
打破
}

cout>std::ws
跳过此行上所有可能的尾随空格(换行符已被
std::getline()
删除)。之后,应该使用流,如果确实没有进一步的输入,则设置
eof()
标志(这是
eof()
的少数有效用法之一).

很有意义。但在按下enter键时抛出运行时错误的任何数字输入后,代码似乎不起作用,在注释掉行
throw std::runtime\u error
时,代码起作用,但显示“不是数字值,请再次输入”在接受输入之前。我想这是因为在这个浮动输入之前还有其他输入。
返回x;
可能应该用
返回x;
替换
中断
@vsoftco将
中断
替换为
返回x;
修复了错误,谢谢。但是当这个函数是第一个被调用时工作正常。但是当我其他
std::cin
语句在调用此函数之前,它会打印“不是一个数值,请再次输入”,然后进行输入。在抛出'std::invalid_argument'what():stof中止(内核转储)的实例后,输入字符
terminate调用时出现此错误
我做错了什么吗?@ShoaibAhmed否,这意味着初始字符串根本无法转换,例如,以字符开头。您可以用
try/catch
块将行
x=std::stof…
包围起来。请参阅更新的编辑。
float validInput()
{
    float x;
    // cout<< flush; There is *NO* reason to flush cout: it is flushed when using cin
    for (std::string line; std::getline(std::cin, line); ) {
        std::istringstream lin(line);
        if (lin >> x && (lin >> std::ws).eof()) {
            break;
        }
        cout << "Not a numeric value please enter again\n";
    }
    throw std::runtime_error("reached end of input before getting a valid value!");
    return x;
}