Read from string into stringstream

25,955

You can test the return value of >>.

while (ss >> t) {
    lis.push_back(t);
}

It's not specified to read circularly. It's ss << s appending "1 2 3 4" to the end of the stream.

Before the 1st loop:

""

After 1st ss << s:

"1 2 3 4"

After 1st ss >> t:

" 2 3 4"

After 2nd ss << s:

" 2 3 41 2 3 4"

Then it's clear why you get 1 2 3 41 2 3 41 2 3 41 if there is no trailing space in s.

Share:
25,955
Leolo
Author by

Leolo

Updated on July 17, 2022

Comments

  • Leolo
    Leolo almost 2 years

    When I try to parse whitespace seperated double values from a string, I found this curious behaviour that the string is read out in a cyclic manner.

    Here's the program:

    stringstream ss;
    string s("1 2 3 4");
    double t;
    list<double> lis;
    
    for(int j=0; j!=10; ++j){
        ss << s;
        ss >> t;
        lis.push_back(t);
    }
    
    for(auto e : lis){
        cout << e << " ";
    }
    

    Here the output:

    1 2 3 41 2 3 41 2 3 41
    

    If I append a trailing space as s= "1 2 3 4 "; I get

    1 2 3 4 1 2 3 4 1 2 
    

    Now the questions:
    1) If I don't know how many entries are in the string s, how do I read all into the list l?
    2) which operator<< am I actually calling in ss << s;? Is it specified to read circularly?
    3) Can I do the parsing in a better way?

    Thanks already!


    Here's the fixed code (thanks to timrau):

    // declarations as before
    ss << s;
    while(ss >> t){
       lis.push_back(t);
    }
    // output as before  
    

    This produces:

     1 2 3 4  
    

    as desired. (Don't forget to clear your stringstream by ss.clear() before treating the next input. ;))

    Another useful comment from HeywoodFloyd: One could also use boost/tokenizer to "split" the string, see this post

  • Leolo
    Leolo about 10 years
    Got it! Thx a lot. I was thinking that the << would read space seperated words as the cin >> some_string does.