首页 > 解决方案 > 验证双精度值输入

问题描述

我写了一个程序,用用户输入计算圆柱和矩形区域。但我想改进我的代码。当用户输入字符而不是数字时,它应该输出错误消息。所以我写了一些额外的代码,但它不能正常工作。

#include <iostream>
#include <ctype.h>

using namespace std;
class area_cl
{
public:
    double height, width;
};
class rectangle : public area_cl
{
public:
    double area(double h, double w)
    {
        return h * w;
    }
};
class cylinder : public area_cl
{
private:
    double pi = 3.14;

public:
    double area(double h, double w)
    {
        return 2 * pi * (w / 2) * ((w / 2) + h);
    }
};
int main()
{
    area_cl dimension;
    rectangle obj1;
    cylinder obj2;
    bool flag = true;

    while (flag)
    {

        cout << "What is the dimensions? (Height and Width)" << endl;

        cin >> dimension.height >> dimension.width;

        if (isdigit(dimension.height) && isdigit(dimension.width))
        {
            flag = false;
        }
        else
        {
            cout << "You are not entered number,please try again." << endl;
        }
    }

    cout << "Rectangle's area is : " << obj1.area(dimension.height, dimension.width) << endl;
    cout << "Cylinder's area is : " << obj2.area(dimension.height, dimension.width) << endl;
    return 0;
}
  1. 我想过使用isdigit(),但我的输入变量必须是双精度类型,并且可能我的代码为此崩溃。C++ 中是否有任何方法,例如 C# 中的解析?

  2. 我还考虑过使用 ASCII 码控制输入。例如if ( char variable >= 48 && char variable <= 57),但我无法让它工作。

我更愿意用第一个选项来解决这个问题,但我完全愿意接受其他解决方案。

谢谢。

标签: c++validationinputiocin

解决方案


1.我想过使用isdigit(),但我的输入变量必须是双精度类型,可能我的代码为此崩溃。C++ 中是否有任何方法,例如 C# 中的解析?

isdigit只是检查数字,它不适合你需要的东西。是的,在 C++ 中有更好的解析方式,不像 C#,但至少和 IMO 一样好(我会提前回到它)。


2. 我也想过用 ASCII 码控制输入。例如if ( char variable >= 48 && char variable <= 57),但我无法让它工作。

这也不是一个好的选择,您需要doubles并且这会使逐位检查变得不必要地复杂,特别是因为这可以通过其他方式很容易地实现。

为了将来参考,在使用字符比较时,您应该使用字符文字,并非所有编码都具有与 ASCII 相同间隔的数字代码:

if (char variable >= '0' && char variable <= '9')

会更合适。


我更愿意用第一个选项来解决这个问题,但我完全愿意接受其他解决方案。

我能想到的更简单、更惯用的方法是使用cin返回值来检查输入是否确实有效,如果不是则采取措施(清除缓冲区和重置流错误状态),然后再次询问有效值,您的代码重构看起来类似于:

while (flag)
{
    cout << "What are the dimensions? (Height and Width)" << endl;
    if (cin >> dimension.height && cin >> dimension.width)
    {
        flag = false;
    }
    else
    {
        cin.clear(); // clear error flags
        cin.ignore(numeric_limits<streamsize>::max(),'\n'); // clear buffer *
        cout << "You have not entered numbers, please try again" << end;
    }
}

或者,更好的国际海事组织:

cout << "What are the dimensions? (Height and Width)" << endl << ">"; // **
while (!(cin >> dimension.height && cin >> dimension.width))           
{
    cin.clear(); // clear error flags
    cin.ignore(numeric_limits<streamsize>::max(), '\n'); // clear buffer *
    cout << "You have not entered numbers, please try again" << endl << ">";
}

*-cin.ignore(numeric_limits<streamsize>::max(),'\n');可能需要包含<limits>标题。

此例程清除输入缓冲区,其中将包含无法解析的字符,以防发生读取错误。

您可以像这样阅读它:

“在找到换行符之前,忽略(并从缓冲区中删除)所有存在的字符”

这将删除所有字符,直到\n找到 a,这是输入缓冲区中的最后一个字符,当您按下时添加Enter


**- 请注意,我在第二个选项中更改了消息。输入消息仅在循环开始时发出一次,错误消息仅在输入失败时询问新的输入。您现在拥有它的方式,如果输入失败,消息流将是:

What is the dimensions? (Height and Width)
1.9 a
What is the dimensions? (Height and Width)
You are not entered number,please try again 
_

我会比较喜欢:

What are the dimensions? (Height and Width)
> 1.9 a
You have not entered numbers, please try again 
>_

推荐阅读