scimaks
scimaks

Reputation: 153

Clearing C++ string at the end of a while loop

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];
}

Upvotes: 1

Views: 1774

Answers (2)

Michael Anderson
Michael Anderson

Reputation: 73490

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 (...) {        
     ...
   }
}

Upvotes: 1

Gene
Gene

Reputation: 179

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

Upvotes: 0

Related Questions