注册 登录
编程论坛 C++教室

请高手指点一下,源码哪里有问题?

mfs111116 发布于 2012-08-22 07:04, 547 次点击
本源码来自《21天学通C++》(Jesse Liberty著)第一篇学习总结。
目的是通过一个显示菜单进行功能操作,可以画出矩形、计算面积、周长以及重新设定矩形的长、宽,最后,可以退出菜单和程序。
问题是:哪里出了错? 在输入字符型选择后,程序不停止……
#include<iostream.h>
 
enum CHOICE{DrawRect=1,GetArea,GetPerim,ChangeDimensions,Quit};//枚举型常量
class Rectangle
{
public:
    Rectangle(int width,int height);
    ~Rectangle();

    int GetHeight()const{return itsHeight;}
    int GetWidth()const{return itsWidth;}
    int GetArea()const{return itsHeight*itsWidth;}
    int GetPerim()const{return 2*itsHeight+2*itsWidth;}
    void SetSize(int newWidth,int newHeight);

private:
    int itsWidth;
    int itsHeight;

};
void Rectangle::SetSize(int newWidth,int newHeight)
{
    itsWidth=newWidth;
    itsHeight=newHeight;
}

Rectangle::Rectangle(int width,int height)
{
    itsWidth=width;
    itsHeight=height;
}
Rectangle::~Rectangle(){}

int DoMenu();
void DoDrawRect(Rectangle);
void DoGetArea(Rectangle);
void DoGetPerim(Rectangle);

int main()
{
    Rectangle theRect(30,5);

    int choice=DrawRect;
    int fQuit=false;

    while(!fQuit)  //死循环
    {
        
        choice=DoMenu();
    if((choice<DrawRect)||(choice>Quit))
        {
            cout<<"请重新选择\n";
            
            continue;
        }
        switch(choice)
        {
        case DrawRect:
            DoDrawRect(theRect);
            break;
        case GetArea:
            DoGetArea(theRect);
            break;
        case GetPerim:
            DoGetPerim(theRect);
            break;
        case ChangeDimensions:
            int newLength,newWidth;
            cout<<"\nNew width:";
            cin>>newWidth;
            cout<<"New height:";
            cin>>newLength;
            theRect.SetSize(newWidth,newLength);
            DoDrawRect(theRect);
            DoGetArea(theRect);
            
            DoGetPerim(theRect);

            break;
        case Quit:
            fQuit=true;
            cout<<"\n退出……\n\n";
            break;
        default :        //可能永远不会出现。但在本程序中,输入字母,出现循环不停            
            cout<<"选择错误\n";
            fQuit=true;
            break;

        }
    }
        
    return 0;
}
int DoMenu()
{
    int choice;

    cout<<"\n\n****Menu****\n\n";
    cout<<"(1)画出矩形。\n";
    cout<<"(2)算出面积.\n";
    cout<<"(3)计算周长.\n";
    cout<<"(4)重新设置矩形。\n";
    cout<<"(5)退出。\n\n";

    cin>>choice;
    return choice;
}
void DoDrawRect(Rectangle theRect)
{
    int height=theRect.GetHeight();
    int width=theRect.GetWidth();
    for(int i=0;i<height;i++)
    {
        for(int j=0;j<width;j++)
        {
            cout<<"*";
        }
        cout<<"\n";
    }
}

void DoGetArea(Rectangle theRect)
{
    cout<<"Area:"<<theRect.GetArea()<<endl;
}

void DoGetPerim(Rectangle theRect)
{
    cout<<"周长是:"<<theRect.GetPerim()<<endl;
}
            
5 回复
#2
mfs1111162012-08-22 07:06
源码可以直接复制到编译器上运行,请高手帮忙看一下,应该怎么修改?
#3
pangding2012-08-22 10:07
你的 DoMenu 里,int choice; 之后再 cin >> choce; 这时:
cin 希望能读到一个数字,但它发现缓存里其实是一个字母,比如 a。它会读取失败,那个 a 还会留在输入缓存里。根据不同的要求,这里可以有各种处理方法。
比如:
程序代码:
int DoMenu()
{
    int choice;

    cout<<"\n\n****Menu****\n\n";
    cout<<"(1)画出矩形。\n";
    cout<<"(2)算出面积.\n";
    cout<<"(3)计算周长.\n";
    cout<<"(4)重新设置矩形。\n";
    cout<<"(5)退出。\n\n";

    if(!(cin>>choice)) {    // 判断 cin 是否遇到错误。若没遇到,if 里的语句不执行。
        char ch;   // 声明一个临时变量。
        cin.clear();    // 先清除输入流的错误状态
        cin.get(ch);   // 然后从流中读入一个字符。比如之前输入的是 a,那么它还留在缓冲区里,这时将被读到。
        cerr << "非数字输入:" << ch << "  ";    // 告诉用户为什么读取失败。

        choice = -1;    // 然后把 choice 赋成一个不合理的值,传回去。根据主函数的逻辑,一会就会再次循环要求用户重新输入。
    }

    return choice;
}

#4
mfs1111162012-08-22 14:05
非常感谢
#5
xuexi0052012-08-23 05:40
mfs111116,编程习惯很好,还写注释
#6
mfs1111162012-08-24 12:32
呵呵,新手,正在学习中,请大家多多指教。
1