【问题标题】:Why is my if statement not evaluating false when it should be?为什么我的 if 语句在应该评估的时候没有评估为 false?
【发布时间】:2021-05-15 21:29:35
【问题描述】:

在我程序的这一部分中,我想取出字符串 highScore 中的前导 0。这是我所拥有的(不是整个程序;这只是我遇到问题的部分):

//take out leading 0s
for (int i = 0; highScore.at(i) != '\0'; i++)
{
    if (highScore.at(i) == '0')
        highScore = highScore.erase(0, 1);
    else
      break;
}

highScore 字符串中包含字符串“000500000”,因此在变量 i 变为 3 后,它应该离开循环(至少,这是我想要它做的),而是继续循环遍历字符串 2多次,然后输出此错误:

terminate called after throwing an instance of 'std::out_of_range'
  what():  basic_string::at: __n (which is 5) >= this->size() (which is 4)

我对此有点困惑,因为我认为我没有做任何会使字符串超出范围的事情。

【问题讨论】:

  • 什么是highScore?提示:std::string 是否会包含一个 NUL 字节,除非你明确地把一个字节放在那里?你的意思可能是i < highScore.length()
  • C 字符串以 null 结尾,但 C++ std::strings 不是。
  • highScore = highScore.erase(0, 1); 1) 分配是多余的,只需erase 就足够了。 2) 您检查了i'th 索引,但始终擦除索引0。 3) 单步执行循环并在前几次迭代中注意highScorei
  • 啊,我明白了,我没有意识到 C++ 字符串也不是以空值结尾的。谢谢@dxiv,我现在意识到了!
  • "std::string is not null-terminated" 需要一些澄清。 std::string 内部使用的缓冲区 以空值终止,您可以使用 .data().c_str() 成员访问它。但是你不能通过迭代字符串对象来访问那个'\0',并且它不包含在.size()中。

标签: c++ loops for-loop if-statement


【解决方案1】:

你既缩短了字符串又推进了下标。这会让你很快出界。您的if 应该始终测试.at(0),并且您的循环,正如上面提到的其他人,应该测试size()。你不能用'\0'寻找结尾。

【讨论】:

  • 哇,完全看清了这个事实。谢谢,这解决了问题!
【解决方案2】:

问题是每次调用highScore.erase()String highScore 的长度都会改变。 我更喜欢你先计算零的数量,然后在最后应用.erase()。 看看

int zeroCount = 0;
for(int i=0; i<highScore.length(); i++){
     if(highScore.at(i) == '0'){
          zeroCount++;
     }
     else{
          break;
     }
}
highScore.erase(0,c);

【讨论】:

  • 可能:auto zeroCount = std::distance(highScore.begin(), std::find_if(highScore.begin(), highScore.end(), [](char c){ return c != '0'; });
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-03-15
  • 2014-05-11
  • 1970-01-01
  • 2015-12-07
  • 2018-10-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多