【问题标题】:Assertion error, string subscript out of range断言错误,字符串下标超出范围
【发布时间】:2012-11-10 08:11:05
【问题描述】:

我几乎完成了这个菜单并按照我想要的方式工作。但是,当我在不输入任何内容的情况下按 Enter 时出现断言错误。这是代码

#include <iostream>
#include <cstdlib>
#include <string>
#include <sstream>
#include <iomanip>


using namespace std;

bool menu ()
{
 string input = "";
 bool exitVar;

 do
 {
 system("cls");

 cout << "               _       _   _   _       _   _ _ _  " << endl
      << "              |_|_   _|_| |_| |_|_    |_| |_|_|_| " << endl
      << "              |_|_|_|_|_| |_| |_|_|_  |_| |_|_    " << endl
      << "              |_| |_| |_| |_| |_| |_|_|_| |_|_|   " << endl
      << "              |_|     |_| |_| |_|   |_|_| |_|_ _  " << endl
      << "              |_|     |_| |_| |_|     |_| |_|_|_| " << endl
      << "               _ _   _       _   _ _ _   _ _ _   _ _     _ _ _   _ _      " << endl
      << "             _|_|_| |_|     |_| |_|_|_| |_|_|_| |_|_|_  |_|_|_| |_|_|_    " << endl
      << "            |_|_    |_|  _  |_| |_|_    |_|_    |_|_|_| |_|_    |_|_|_|   " << endl
      << "              |_|_  |_|_|_|_|_| |_|_|   |_|_|   |_|_|   |_|_|   |_|_|_    " << endl
      << "             _ _|_| |_|_| |_|_| |_|_ _  |_|_ _  |_|     |_|_ _  |_| |_|_  " << endl
      << "            |_|_|   |_|     |_| |_|_|_| |_|_|_| |_|     |_|_|_| |_|   |_| " << endl;

 cout << "\n            Welcome to Psuedo Mine Sweeper!!\n\n\n\n";

 cout << "                  <S>TART"
     << "\n\n                   <E>XIT\n\n";



    cout << "\t\t\tPlease enter a valid menu option: ";
    getline(cin,input);

    input[0] = toupper(input[0]);

}while(input[0] != 'S' && input[0] != 'E' || input.length() != 1 || cin.peek() != '\n');

if (input[0] == 'S')
    exitVar = true;
else
    exitVar = false;

return exitVar;

}

我对调试断言值没有太多经验。我尝试独立运行菜单

【问题讨论】:

  • 尝试在getline之后打印输入,你可能会看到问题!

标签: c++ assertion


【解决方案1】:

这里的问题是,当您按下回车键时,getline 会将input 设置为空字符串,因为没有输入任何输入。

这意味着它的长度为 0,但是当您调用 input[0] 时,您要求输入其中的第一个字符。由于它没有,因此会引发断言错误。

要解决这个问题,在调用getline 后检查input 是否为空,如果是,请使用continue 重新开始循环。

【讨论】:

  • 啊啊啊啊,有道理。如果我将“字符串输入”的定义更改为某个值而不是将其留空,是否可以解决问题。现在去试试,只是猜测。非常感谢!
  • 不,没用....嗯。我想这行不通,因为当我尝试 getline 时,如果按下 enter,它会将字符串重新定义为空。我该如何解决这个问题?
  • 检查字符串是否为空,如果是调用continue。这将使您跳出当前的循环迭代并重新开始
【解决方案2】:

您需要更改循环条件。

while (input.length() != 1 || (toupper(input[0]) != 'S' &amp;&amp; toupper(input[0]) != 'E'));

|| 是从左到右测试的,因此您必须检查长度是否正确在检查第一个字符之前。将toupper 作为循环条件的一部分也将有所帮助,因为这样首先会检查长度。我也删除了对cin.peek() 的调用,但不确定我是否理解那是什么意思。

你可以用一些布尔逻辑重写整个事情以使其更清晰。

while (!(input.length() == 1 &amp;&amp; (toupper(input[0]) == 'S' || toupper(input[0]) == 'E')));

一般来说,否定的次数越少,复杂的布尔逻辑就越容易理解。

【讨论】:

  • 他还在循环条件前调用了input[0]
  • 他做到了。我会修改我的答案。
  • 修复了!照你说的做了,并在循环之前删除了我调用 input[0] 的部分。很高兴知道 while 循环从左到右执行,这让我忽略了。非常感谢你们!
  • @DustinBurns 不是 while 循环,||&amp;&amp;||&amp;&amp;在这方面比较特殊,大部分运营商都不是这样工作的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-31
  • 2013-04-22
  • 2012-04-27
  • 2021-06-29
相关资源
最近更新 更多