Anubhav Agarwal
Anubhav Agarwal

Reputation: 2062

Array subscript operator on Vectors

I was writing a code to tokenize a string wrt delimeters ",".

    void Tokenize(const string& str, vector<string>& tokens, const string& delimeters)
    {
      // Skip delimiters at beginning.
      string::size_type lastPos = str.find_first_not_of(delimiters, 0);
      // Find first "non-delimiter".
      string::size_type pos     = str.find_first_of(delimiters, lastPos);

      while (string::npos != pos || string::npos != lastPos)
      {
         // Found a token, add it to the vector.
         tokens.push_back(str.substr(lastPos, pos - lastPos));
         // Skip delimiters.  Note the "not_of"
         lastPos = str.find_first_not_of(delimiters, pos);
         // Find next "non-delimiter"
        pos = str.find_first_of(delimiters, lastPos);
      }
    }

    int main()
    {
       string str;
       int test_case;
       cin>>test_case;
       while(test_case--)
       {
           vector<string> tokens;
           getline(cin, str);
           Tokenize(str, tokens, ",");
           // Parsing the input string 
           cout<<tokens[0]<<endl;
       }
       return 0;
    }

It gives segmentation fault on running. When I debugged it the line

    cout<<tokens[0]<<endl 

was the cause of problem.I can't understand why because at cplusplus.com it uses the [ ] operartors for accesing the values of vectors

Upvotes: 0

Views: 556

Answers (2)

Benjamin Lindley
Benjamin Lindley

Reputation: 103713

cin>>test_case; // this leaves a newline in the input buffer
while(test_case--)
{
    vector<string> tokens;
    getline(cin, str); // already found newline
    Tokenize(str, tokens, ",");  // passing empty string

Without looking at your Tokenize function, I would guess that an empty string results in an empty vector, which means when you print tokens[0], that element does not actually exist. You need to make sure your input buffer is empty before you call getline. You could put a call to cin.ignore() right after your number input, for example.

You could also forgo operator>>, and only use getline. Then do string to number conversions with your favorite method.

Upvotes: 1

Dietmar K&#252;hl
Dietmar K&#252;hl

Reputation: 153840

Is it possible that the read using std::getline() wasn't successful? In this case the string would be empty and using the subscript operator would crash. You should always test whether reading was successful after trying to read, e.g.:

if (std::getline(std::cin, str)) {
    // process the read string
}

Upvotes: 1

Related Questions