420kscott
420kscott

Reputation: 3

String subscript out of range (C++)

I am having trouble with this blasted exam question that i cannot put down, visual C++ 2010 keeps telling me: "Expression: string subscript out of range". I figured that I am running the loop longer than the length of the "inStringP.length()" so I have added & subtracted 1 or 2 from the integer in the for loop's conditional test but this leads to no success. Google isn't feeling its usual genius self today either.....

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

Upvotes: 0

Views: 380

Answers (5)

billz
billz

Reputation: 45420

Your application crashes is because below statement doesn't allocate any elements for temp, accessing temp[0] is undefined behavior.

string temp;

If you want to use temp inside removeChar function, the better way is to pass const reference to inStringP

string removeChar(const string& inStringP){
}

By doing that, you don't need to make a copy to inStringP when enter removeChar function.

The better way is to follow erase-remove idiom:

Try:

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

Upvotes: 2

Fredrick Gauss
Fredrick Gauss

Reputation: 5166

I would recommend;

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

Because your logic gives no-compile time error but it is a run time error. Your code actually works as:

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';

which is an out of range error.

Upvotes: 0

Suvarna Pattayil
Suvarna Pattayil

Reputation: 5239

When you use std::string you can make use of arithmetic operators too.

You can do something like this,

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

I tried your code on g++ 4.6.3 it did not give any error. However, it gave a blank temp at the end of for loop;

With, temp[i] = inString[i] the compiler doesn't yet have a size for temp

Also, if you use same i for temp and inStringP Suppose, we are at character e it will skip the if block and +1 i. The corresponding location in temp will remain whatever it is.

Also, string.length() returns length of string excluding \0

Upvotes: 0

masoud
masoud

Reputation: 56509

resize temp before using

string temp;

temp.resize(inStringP.size());

When you don't know the real size in the beginning, you can append, push_back and operator+=:

temp.append(1, inStringP[i]);

or

temp.push_back(inStringP[i]);

or

temp += inStringP[i];

Upvotes: 1

Jimbo
Jimbo

Reputation: 4515

could you try using string.erase()?

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

The iterator version will let you delete a character... search through the string using the iterator and then delete it using the erase function, which accepts the iterator as an argument

EDIT: See billz's answer... very nice!

Upvotes: 0

Related Questions