0

下面是我当前作业的代码。该程序使用几个重载的运算符来提示用户输入他们三餐中每餐的名称和卡路里计数,然后显示结果。通过第一遍一切正常,但是在第二遍中它表现得有点奇怪。无论提示用户的第一餐是什么,都将保留上一轮的名称。可以输入该餐和接下来的三餐的所有其他值,但是无论如何,第一餐的名称保持不变。只是希望有人可以帮助我指出正确的方向。谢谢!

#include <iostream>
#include <iomanip> 
#include <string>

using namespace std;

/*********************************************************************
File Name: meal.cpp
Author: Neal Rodruck
Date: 7/8/12
Purpose: To provide intergallactic travelers a means of measuring their
         daily caloric intake.
*********************************************************************/

class Meal
{
private:
    string name;
    int calorie;
public:
    //Class constructors
    Meal() : name("Meal 1"), calorie(0)
    {}
    Meal(string name, int calorie) : name(name), calorie(calorie)
    {
        while (calorie < 1)
        {
            cout << "Please enter a caloric value greater than 0!: ";
            cin >> calorie;
        }
    }

    //Class destructor
    Meal::~Meal()
    {}

    //get functions
    string getName() { return name; }
    int getCalorie() { return calorie; }

    //set functions
    void setName(string n) { name = n; }
    void setCalorie(int c) { calorie = c; }

    //Overloaded operators
    friend ostream &operator<<(ostream &out, Meal m);
    friend istream &operator>>(istream &in, Meal &m);
    friend Meal operator+(Meal a, Meal b);
};

//Calculate two or more meal objects to obtain daily total
Meal operator+(Meal a, Meal b)
{
    return Meal("Daily Total", a.calorie + b.calorie);
}

//Prompt user for name and calorie information 
//for Meal object as well as test for greater 
//than zero calorie total
istream &operator>>(istream &in, Meal &m)
{
    char name[21];
    int calorie = 0;

    cout << "Enter name: ";
    cin.getline(name, 21);  
    cout << "Enter calories: ";
    in >> calorie;

    while (calorie < 1)
    {
        cout << "Please enter a caloric value greater than 0!: ";
        cin >> calorie;
    }

    m.setName(name);
    m.setCalorie(calorie);
    cin.ignore();

    return in;
}

//Display object information
ostream &operator<<(ostream& out, Meal m)
{
    out << "Name: " << m.name << " Calories: " << m.calorie;
    return out;
}

//function prototypes
void makeNull(Meal& breakfast, Meal& lunch, Meal& dinner);
void introduction();
void display(Meal b, Meal l, Meal d, Meal t);
void end();
void enterMealInfo(Meal& breakfast, Meal& lunch, Meal& dinner);

int main()
{
    //Display introductory message
    introduction();

    //Meal Objects
    Meal breakfast;
    Meal lunch;
    Meal dinner;

    //Capture user response
    char response = ' ';

    //Use loop to allow user to enter information for 
    //more than one day
    while (response != 'n')
    {


        //Prompt user for meal information
        enterMealInfo(breakfast, lunch, dinner);

        //Use information captured to create Daily Total meal object
        Meal total(breakfast + lunch + dinner);

        //Display results
        display(breakfast, lunch, dinner, total);

        //Prompt user for more input
        cout << "Would you like to check again? Please selct \"y\" or \"n\": ";
        cin >> response;
        response = tolower(response);
    }

    //Display exit message
    end();

    return 0;
}

//Display introductory message
void introduction()
{
    cout << "Welcome to The Voyager Trek!";
    cout << "\nPlease use this app to keep track of your daily caloric intake!\r\n";
}

//Display meal and summary information
void display(Meal b, Meal l, Meal d, Meal t)
{
    cout << "\n" << left << setw(20) << "Meal" << right << setw(20) << "Calories";
    cout << "\n" << left << setw(20) << b.getName();
    cout << right << setw(20) << b.getCalorie();
    cout << "\n" << left << setw(20) << l.getName();
    cout << right << setw(20) << l.getCalorie();
    cout << "\n" << left << setw(20) << d.getName();
    cout << right << setw(20) << d.getCalorie();
    cout << "\n" << "----------------------------------------";
    cout << "\n" << left << setw(20) << t.getName();
    cout << right << setw(20) << t.getCalorie() << "\n";
}

//Display exit message
void end()
{
    cout << "\r\nThank you for using our app, goodbye!\r\n";
    system("pause");
}

//Using meal objects passed by reference this function 
//will populate appropriate objects with name and calorie
//information
void enterMealInfo(Meal& breakfast, Meal& lunch, Meal& dinner)
{
    cout << "\r\nWhat did you have for breakfast?\r\n";
    cin >> breakfast;
    cout << "What did you have for lunch?\r\n";
    cin >> lunch;
    cout << "What did you have for dinner?\r\n";
    cin >> dinner;
}
4

2 回答 2

4

问题是在 main 的 while 循环中使用这一行:

cin >> response;

当用户按下回车键时,输入缓冲区中会留下一个尾随换行符。由于您的函数enterMealInfo使用 getline,并且 getline 正在寻找换行符,因此它会立即找到它正在寻找的内容,因此它不会提示用户。如果在循环末尾添加此行:

cin.ignore();

它将删除换行符。


在旁注中,正如 Ree 先生在下面的评论中提到的那样,您的输入运算符有点奇怪。您将 istream 作为第一个参数,但您不使用它。相反,您只需使用cin. 您应该使用传入的 istream,如 inin.getline(name, 21);in >> calorie;...

于 2012-07-09T03:16:52.637 回答
0

可以肯定的是,您忘记同步输入。

试试这个:

...
while (response != 'n')
{
    //Sync the input stream 
    cin.sync();

    //Prompt user for meal information
    enterMealInfo(breakfast, lunch, dinner);
...
于 2012-07-09T01:34:11.300 回答