【问题标题】:String subscript out of range (C++)字符串下标超出范围 (C++)
【发布时间】:2013-04-22 19:20:21
【问题描述】:

我遇到了这个我无法放下的爆炸性考试问题,visual C++ 2010 不断告诉我:“表达式:字符串下标超出范围”。我认为我运行的循环比“inStringP.length()”的长度长,所以我在 for 循环的条件测试中从整数中加减 1 或 2,但这并没有成功。谷歌今天也没有感受到它往常的天才自我......

#include <iostream>
#include <cstdlib>
#include <string>
#include "stdAfx.h"
using namespace std;

string removeChar(string inStringP){
   string temp;
   for(int i=0;i<inStringP.length()-1;i++){
      if(inStringP[i]!='p'){
         temp[i]=inStringP[i];
      }
   }
   return temp;
}

int main(){
   string sample = "Peter picks a peck of pickled peppers";
   cout<<removeChar(sample)<<endl;

   system("PAUSE");
   return EXIT_SUCCESS;
}

【问题讨论】:

    标签: c++ indexoutofboundsexception


    【解决方案1】:

    您的应用程序崩溃是因为下面的语句没有为temp 分配任何元素,访问temp[0]未定义的行为

    string temp;
    

    如果你想在 removeChar 函数中使用temp,更好的方法是将 const 引用传递给 inStringP

    string removeChar(const string& inStringP){
    }
    

    这样,在进入removeChar函数时就不需要复制到inStringP了。

    更好的方法是关注erase-remove idiom

    试试:

    string removeChar(string inStringP)
    {
        return inStringP.erase(std::remove(sample.begin(), sample.end(), 'p'), sample.end());
    }
    

    【讨论】:

      【解决方案2】:

      我会推荐;

      string removeChar(string inStringP){
         string temp;
         int len = inStringP.length();
         for(int i = 0;i < len;i++){
            if(inStringP[i] != 'p'){
              temp.push_back(inStringP[i]);
            }
         }
         return temp;
      }
      

      因为您的逻辑给出了无编译时错误,但它是运行时错误。你的代码实际上是这样工作的:

      string temp;
          temp[0] = 'P';
          temp[1] = 'e';
          temp[2] = 't';
          temp[3] = 'e';
          temp[4] = 'r';
          temp[5] = ' ';
          //s[6] = 'p';
          temp[7] = 'i';
      

      这是一个超出范围的错误。

      【讨论】:

        【解决方案3】:

        当您使用std::string 时,您也可以使用算术运算符。

        你可以这样做,

           for(int i=0;i<=inStringP.length();i++)
           {
              if(inStringP[i]!='p')
              {
                 temp += inStringP[i];
                 cout<<temp<<endl;
              }
           }
        

        我在g++ 4.6.3 上尝试了您的代码,它没有给出任何错误。然而,它给了 for 循环末尾的空白 temp

        对于temp[i] = inString[i],编译器还没有temp的大小

        另外,如果您对tempinStringP 使用相同的i 假设,我们在字符e,它将跳过if block 和+1 i。相应的 temp 中的位置将保持不变。

        另外,string.length() 返回字符串的长度,不包括\0

        【讨论】:

          【解决方案4】:

          resizetemp使用前

          string temp;
          
          temp.resize(inStringP.size());
          

          一开始不知道实际尺寸时,可以appendpush_backoperator+=

          temp.append(1, inStringP[i]);
          
          or
          
          temp.push_back(inStringP[i]);
          
          or
          
          temp += inStringP[i];
          

          【讨论】:

          • 我不知道为什么这被否决了?如果您通过元素访问 string temp ,则需要给它一些大小,否则编译器将不知道它有多大。当你说 temp[i]=inStringP[i] 时,temp[i] 可能越界了?
          • 感谢大家的精彩回答,但我必须使用“temp.resize ....”,第一次工作,再次感谢该死的快速响应!
          【解决方案5】:

          您可以尝试使用 string.erase() 吗?

          http://www.cplusplus.com/reference/string/string/erase/

          迭代器版本将允许您删除一个字符...使用迭代器搜索字符串,然后使用擦除函数将其删除,该函数接受迭代器作为参数

          编辑:查看 billz 的回答...非常好!

          【讨论】:

            猜你喜欢
            • 2012-04-27
            • 2015-03-31
            • 2014-08-04
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多