我编写了一个程序,通过用户输入计算圆柱体和矩形区域。但我想改进我的代码。当用户输入一个字符而不是数字时,它应该输出一条错误消息。所以我写了一些额外的代码,但它不能正常工作。
#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;
}
}
或者,更好的IMO:
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
,这是输入缓冲区中的最后一个字符,当您按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
>_
isdigit()
检查字符是否为数字。当你给它传递一个double时,它将被转换为int。假设你的输入是1.2,它被转换为(int(1,它不是数字"0"到"9"。
您可以使用cin.fail()
来确定它是否能够获得输入。如果没有,请清除失败状态,并使用无法读取的数据的cin.ignore()
刷新stdin。以相似方式覆盖的cin.bad()
和cin.eof()
:
#include <limits>
#include <stdlib.h>
...
retry:
cout << "What is the dimensions? (Height and Width)" << endl;
cin >> dimension.height >> dimension.width;
if(cin.bad()) return EXIT_FAILURE;
if(cin.eof()) return EXIT_SUCCESS;
if(cin.fail()) {
cout << "You have not entered number, please try again" << endl << ">";
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), 'n');
goto retry;
}
或非goto变体(与@anastaciu讨论(:
#include <limits>
#include <stdlib.h>
...
for(;;) {
cout << "What is the dimensions? (Height and Width)" << endl;
cin >> dimension.height >> dimension.width;
if(cin.bad()) return EXIT_FAILURE;
else if(cin.eof()) return EXIT_SUCCESS;
else if(cin.fail()) {
cout << "You have not entered number, please try again" << endl << ">";
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), 'n');
} else
break;
}
另一种选择是读取一行文本并对其进行解析。它将允许您提供比丢失所有用户输入更好的错误处理。