c++ - 验证双精度值输入
问题描述
我写了一个程序,用用户输入计算圆柱和矩形区域。但我想改进我的代码。当用户输入字符而不是数字时,它应该输出错误消息。所以我写了一些额外的代码,但它不能正常工作。
#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;
}
我想过使用
isdigit()
,但我的输入变量必须是双精度类型,并且可能我的代码为此崩溃。C++ 中是否有任何方法,例如 C# 中的解析?我还考虑过使用 ASCII 码控制输入。例如
if ( char variable >= 48 && char variable <= 57)
,但我无法让它工作。
我更愿意用第一个选项来解决这个问题,但我完全愿意接受其他解决方案。
谢谢。
解决方案
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
>_
推荐阅读
- xaml - Xamarin.forms 如何从图像按钮获取 ID?
- python - Pyomo 约束和使用 pandas
- python - client.event 不向 json 文件 on_guild_add (discord.py) 添加前缀
- python - 在python中将负整数转换为支持十六进制的二进制补码
- python - ImportError:没有名为 psutil 的模块
- html - 输入验证模板参考 ngFor
- c# - 如何在 asp.net core 3.1 mvc Web 应用程序中将日志保存到数据库?
- apache-kafka - Kafka KSQLDB 服务器日志不断“发现没有提交的分区偏移量”
- sql - 在oracle sql中拆分字符串数组
- vba - 在 Powerpoint 中打开 Word 文档