【问题标题】:Clearing C++ string at the end of a while loop在 while 循环结束时清除 C++ 字符串
【发布时间】:2015-08-23 17:14:31
【问题描述】:

在下面的代码中,我尝试使用 getToppings() 方法输出披萨配料列表。我想在每个内部“while”循环的末尾清除这个浇头列表(即每个新的比萨订单必须在没有浇头的情况下启动)。不幸的是,我没有办法清除我的 listOfToppings 字符串。当我明确使用 .clear() 方法时,前一个披萨的最后一个浇头会转移到新的披萨上。如何清除每个新披萨的 listOfToppings?

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

【问题讨论】:

  • When I explicitly use the .clear() method, the last topping of the previous pizza is transferred to the new pizza. 这意味着您在错误的时间调用它 - 在最后一次迭代之前,而不是之后。在内循环的右大括号之后调用它。
  • 伊戈尔 - 没有骰子。我仍然看到最后一个顶部选择出现在 PizzaOrder 的新实例中。
  • 我正要回答你的问题,但你让我太饿了 - 去吃午饭吧。
  • 那你还是做错了。很难说是什么,因为您还没有显示您实际运行的代码,即进行 clear() 调用的代码。
  • 我在内部循环的末尾添加了带有 list.clear() 的修改后的代码。我想知道这种行为是否与 &listOfToppings 作为参考参数有关。

标签: c++


【解决方案1】:

您可以通过稍微不同的代码结构来避免显式 clear 的需要。

由于每个订单都是一个新的披萨,您应该在外循环内创建一个 PizzaOrder 对象。

int main() {

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

然而,正如 Matt McNabb 在 cmets 中所暗示的那样,原始代码还有很多其他问题。

通过在线检查器运行此程序 (http://www.gimpel.com/html/pcl.htm) 我收到以下警告/信息

  • 成员函数PizzaOrder::getSize(void)可以设为const
  • 忽略函数std::getline的返回值
  • 忽略函数PizzaOrder::setSize(int)的返回值
  • pizza.toppingsOffered[i] 应该是 PizzaOrder::toppingsOffered[i]
  • 忽略函数PizzaOrder::addTopping(int)的返回值

  • 最后一行什么都不做

    PizzaOrder::PizzaOrder() {
         numToppings = 0;
         size=DEFAULT_SIZE;
         toppings;
    }
    
  • 符号“size”的声明隐藏了符号“PizzaOrder::size”,分配给变量“size”的最后一个值未在

    中使用
    PizzaOrder::PizzaOrder(int size) {
       if(!setSize(size))
          size=DEFAULT_SIZE;
    }
    
  • PizzaOrder::addTopping(string topping)PizzaOrder::addTopping(int n) 的返回值 - 隐式转换为布尔值,

  • if (arraySize == 5) 始终评估为 True
  • selectedTopping 仅由其构造函数或析构函数引用

还有更多。

最后一个想法:

初始代码如下所示

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

getToppings 正在添加到列表中,而 clear 正在清除一个无论如何都将被销毁的字符串。

会更好

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

这样每次都清空列表。

但更好的是

  1. 让 getToppings() 返回一个字符串
  2. 将其从列表中移出,因为它不会改变

例如

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

【讨论】:

  • @scimaks 你可能应该调查一下为什么clear() 不起作用 - 也许它揭示了你的 clear 函数中的一个错误或其他地方的另一个错误,这些错误稍后会再次咬你
【解决方案2】:

由于您的列表变量是一个字符串,我的想法是用一个空字符串替换该列表。我认为您应该创建自己的函数来清除该列表,而不是使用该 .clear() 方法。

阅读此link

【讨论】:

  • 我一直在玩这个想法,但没有办法阻止以前每个披萨的最后一个浇头出现在新的披萨中。 Michael 的建议非常有效。
猜你喜欢
  • 2018-06-25
  • 2020-12-24
  • 2023-03-29
  • 2017-05-29
  • 2014-04-20
  • 1970-01-01
  • 1970-01-01
  • 2016-06-14
  • 1970-01-01
相关资源
最近更新 更多