1

In the code below, I'm attempting to output a list of pizza toppings using the getToppings() method. I'd like to clear this listing of toppings at the end of each inner 'while' loop (i.e. each new pizza order must be initiated with no toppings). Unfortunately, I have found no way to clear my listOfToppings string. When I explicitly use the .clear() method, the last topping of the previous pizza is transferred to the new pizza. How can I clear the listOfToppings for each new pizza?

int main()
{
   PizzaOrder pizza;
   string size;
   string toppingSelection;
   bool innerLoop = true;
   bool outerLoop = true;
   int currentToppingsNum;


   // Outer loop
   while (outerLoop)
   {
      // Outer loop

      ...

      // Inner loop
      while (innerLoop && currentToppingsNum < 5)
      {
         pizza.PizzaOrder::getToppings(list);
         cout << "Current Pizza: " << pizza.stringizeSize() << list << "\n\n";
         cout << "Select an item by number (0 when done): \n\n";
         ...
         cout << "Selection: ";
         ...
         ...
            pizza.displayPizza();
      } list.clear();
   }
   return 0;
}

...

void PizzaOrder::getToppings(string &listOfToppings)
{
   for (int i = 0; i < numToppings; i++)
      listOfToppings = listOfToppings + " + " + toppings[i];
}
Michael Anderson
  • 70,661
  • 7
  • 134
  • 187
scimaks
  • 153
  • 1
  • 3
  • 12
  • 1
    `When I explicitly use the .clear() method, the last topping of the previous pizza is transferred to the new pizza.` This means you are calling it at the wrong time - before the last iteration, not after. Call it after the closing brace of the inner loop. – Igor Tandetnik Jun 09 '15 at 03:54
  • Igor - no dice. I'm still seeing the last topping choice appear in new instances of PizzaOrder. – scimaks Jun 09 '15 at 04:00
  • 1
    I was going to answer your question, but you've made me too hungry - going to lunch instead. – Tony Delroy Jun 09 '15 at 04:01
  • Then you are still doing something wrong. Hard to say what, since you haven't shown the code you are actually running, the code that makes that `clear()` call. – Igor Tandetnik Jun 09 '15 at 04:03
  • I've added the revised code with the list.clear() at the end of the inner loop. I'm wondering if the behavior has something to do with &listOfToppings being a reference parameter. – scimaks Jun 09 '15 at 04:06

2 Answers2

1

You can avoid the need for an explicit clear by structuring your code slightly differently.

Since each order is a new pizza, you should create a PizzaOrder object inside the outer loop.

int main() {

   while(true) {
     ...
     if ( size[0] == 'q' || size[0] == 'Q' ) {
       break;
     }
     PizzaOrder pizza;
     ...
     pizza.displayPizza();
   }
}

However as Matt McNabb alludes to in the comments, there's a lot of other issues with the original code.

Running this through an online checker (http://www.gimpel.com/html/pcl.htm) I get the following warnings / info

  • Member function PizzaOrder::getSize(void) could be made const
  • Ignoring return value of function std::getline
  • Ignoring return value of function PizzaOrder::setSize(int)
  • pizza.toppingsOffered[i] should be PizzaOrder::toppingsOffered[i]
  • Ignoring return value of function PizzaOrder::addTopping(int)

  • Last line of this does nothing

    PizzaOrder::PizzaOrder() {
         numToppings = 0;
         size=DEFAULT_SIZE;
         toppings;
    }
    
  • Declaration of symbol 'size' hides symbol 'PizzaOrder::size', Last value assigned to variable 'size' not used in

    PizzaOrder::PizzaOrder(int size) {
       if(!setSize(size))
          size=DEFAULT_SIZE;
    }
    
  • Return value from PizzaOrder::addTopping(string topping) and PizzaOrder::addTopping(int n) - Implicit conversion to Boolean,

  • if (arraySize == 5) always evaluates to True
  • selectedTopping is referenced only by its constructor or destructor

And a bunch more.

One final thought:

Initial code looked like this

while (outerLoop) {
   string list;
   ...
   while (...) {
     PizzaOrder::getToppings(list);
     ...
   }
   list.clear();
}

getToppings is adding to the list, and clear is clearing a string that is about to be destroyed anyway.

Better would be

while (outerLoop) {
   string list;
   ...
   while (...) {
     list.clear();
     PizzaOrder::getToppings(list);
     ...
   }
}

so that the list is cleared each time.

But better yet would be to

  1. make getToppings() return a string
  2. hoist it out of the list since it doesn't change

e.g.

string list = PizzaOrder::getToppings(list);
while (outerLoop) {
   ...
   while (...) {        
     ...
   }
}
Michael Anderson
  • 70,661
  • 7
  • 134
  • 187
  • @scimaks you should probably investigate why `clear()` wasn't working - maybe it is revealing a bug in your `clear` function or another bug elsewhere that will come back to bite you later – M.M Jun 09 '15 at 04:42
0

since your list variable is a string, my idea is replacing that list with an empty string. I think you should create your own function just to clear that list instead of using that .clear() method.

Read this link

Community
  • 1
  • 1
Gene
  • 169
  • 10
  • I had been playing with this idea but found no way to prevent the last topping of each prior pizza from appearing in new pizzas. Michael's suggestion has worked wonderfully. – scimaks Jun 09 '15 at 04:19