Question

for (int i = peekIndex; i < pdp->size(); i++)
{
    string x = pdp->peek();
    if (x.at(0) == 's')
    {
       out << pdp->peek() << endl;
       pdp->moveForward();  
    }
    else
    {
       pdp->moveForward();
    }
}

The error I get is

terminate called after throwing and instance of std::out_of_range
what(): basic_string::at()

Abort

The peek method returns a string in the position of the peekIndex. The moveFowrard method increments the peekIndex. pdp is a vector of size 100. I am supposed to peek and print only words that start with 's' that have been pushed to the <vector>. I am basically done but this part is proving somewhat difficult. Thanks

#include<iostream>
#include<vector>
#include<string>


using namespace std;

class StringDeque {
protected:
vector<string>* elements;
int frontItem;   //CLASS INV: indexes item with least index
int rearSpace;   //CLASS INV: indexes space after item with greatest index
int upperBound;  //For array[0..n-1] this is "n" not "n-1".



public:
StringDeque(int guaranteedCapacity):
elements (new vector<string>( 2*guaranteedCapacity))
frontItem (guaranteedCapacity),
rearSpace ( guaranteedCapacity),
upperBound ( 2*guaranteedCapacity)
{}
proteted:
virtual bool isEmpty() const { return frontItem == rearSpace; }
virtual bool  isFull() const { return rearSpace == upperBound || frontItem == 0; }
virtual int size() const { return rearSpace - frontItem; }

virtual string popRear() {
if (isEmpty()) {
cerr<< "Later we'll define and throw an EmptyQException"<< endl;
return "";
} else {
return elements->at(--rearSpace);
}
}
virtual string popFront() {
if (isEmpty()) {
cerr<<"Later we'll define and throw an EmptyQException"<<endl;
return "";
} else {
return elements->at(frontItem++);
}
}

/** Directions include similarly testing for "full" in the C++ code.
*/
virtual void pushFront(string newItem) {
elements->at(--frontItem)= newItem;
}
virtual void pushRear(string newItem) {
elements->at(rearSpace++) = newItem;
}


virtual string toString() {
string out = "";
for (int i = frontItem; i < rearSpace; i++) {
out += elements->at(i) + " ";
}
  return out;
}
};




  class PeekDeque : public StringDeque {

  private:
  int peekIndex;


  public:
  PeekDeque(int guaranteedCapacity):
  StringDeque(guaranteedCapacity),
  peekIndex(guaranteedCapacity/2)
  {}



  virtual void moveFrontward() {
  if (peekIndex == upperBound) {
  cerr<<"Cannot move past total capacity"<<endl;

  }     else{
      elements->at(peekIndex ++);
           }
   }
  virtual void moveRearward () {
  if (peekIndex == -1) {
    cerr<<"Cannot move below total capacity"<<endl;

  }     else{
     elements ->at( peekIndex--);
           }
    }



    virtual string popFront() {
     cerr<<"Attempt to pop from empty PeekDeque"<<endl;

     }
    virtual string popRear() {
    cerr<<"Attempt to pop from empty PeekDeque"<<endl;
     }

virtual string peek() {
  if (isEmpty()) {
     cerr<<"Cannot peek an Empty index"<<endl;
     return "";
  } else {
     return elements->at(peekIndex + 1);
  }
  }





  virtual string toString() {
  string out = "";
  for (int i = frontItem; i < rearSpace; i++) {
     out += elements->at(i) + " ";
  }
  return out;
  }
  };

  int main(){

  PeekDeque* pdp = new PeekDeque(101);
  pdp->pushFront("oh");
  pdp->pushFront("say");
  pdp->pushFront("can");
  pdp->pushFront("you");
  pdp->pushFront("see");
  pdp->pushRear("any");
  pdp->pushRear("bad bugs");
  pdp->pushRear("on");
  pdp->pushRear("me?");
  for(int i = peekIndex; i<pdp->size(); i++){
    string x =
   if(x.at(0)=='s'){
  cout<<pdp->peek()<<endl;
  pdp->moveForward();  }
     else{
  pdp->moveForward();
}
   }
  }
Was it helpful?

Solution 2

Here's how your container looks like after initial pushes:

0                       202
| ... | ... | ... | ... |
      ^     ^     ^
      |     |     rearSpace
      |     peekIndex
      frontItem

Now, size() returns rearSpace - frontItem, but iteration starts from peekIndex and thus goes beyond rearSpace index, peeking uninitialized (empty) strings.

That's certainly an approximate answer, since your work with indices is a mess. Please be really careful and think it through.

OTHER TIPS

May be your test should be:

    if(!x.empty() && x.at(0)=='s')

I can't tell exactly, without seeing more context, but I'm pretty sure x.empty() is a probable case.

UPDATE:

pdp is a vector of size 100

Are you sure to have used the pdp.resize(100,std::string()); method to ensure all positions are initialized correctly?

it is not empty i have pushed 8 things to pdp

Also std::vector<>::resize() and std::vector<>::push_back() might not work together as you expect. Use either std::vector<>::push_back() or std::vector<>::resize() to give it a pre-allocated size and manipulate entries by index. Always check for std::vector<>::size() for indexed access.

UPDATE 2:

But the real answer is apparently simpler. You have:

virtual string peek() {
  if (isEmpty()) {
     cerr<<"Cannot peek an Empty index"<<endl;
     return ""; // This will certainly result in a string that is empty!
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top