32

Like I have a stringstream variable contains "abc gg rrr ff"

When I use >> on that stringstream variable, it gives me "abc". How can I get the remaining string: " gg rrr ff"? It seems neither str() nor rdbuf() does this work.

JFMR
  • 23,265
  • 4
  • 52
  • 76
draw
  • 4,696
  • 6
  • 31
  • 37

6 Answers6

41

You can use std::getline to get the rest of the string from the stream:

#include <iostream>
#include <sstream>

using namespace std;

int main() {
        stringstream ss("abc gg rrr ff");
        string s1, s2;
        ss >> s1;
        getline(ss, s2); //get rest of the string!
        cout << s1 << endl;
        cout << s2 << endl;
        return 0;
}

Output:

abc
gg rrr ff

Demo : http://www.ideone.com/R4kfV

There is an overloaded std::getline function in which a third parameter takes a delimiter upto which you can read the string. See the documentation of std::getline:

Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • @draw: I can only guess, but maybe it does read in everything through `operator>>` and only stuffs in the whitespace delimiters between the reads? :| – Xeo Jun 08 '11 at 23:34
  • 2
    @draw (and @Xeo): `std::getline` respects the stream behavior. And in stream behaviour you cannot read *same* input more than once. This is what stream means. See my answer here to know what stream means, in detail : http://stackoverflow.com/questions/6010864/why-copying-stringstream-is-not-allowed/6010930#6010930 – Nawaz Jun 08 '11 at 23:37
  • 2
    It works because it does the same thing that `std::getline` does when applied to `std::cout`: starting at the current stream position, read until the delimiter (`\n` by default) or end-of-file. – Karl Knechtel Jun 09 '11 at 00:26
  • 5
    Since string may contains '\n', `getline(ss, s2, '\0');` might be better. – user1024 Jul 01 '17 at 08:19
  • When doing this with Visual Studio 2017, I actually get a space at the first position of the second string, like " gg rrr ff". I thought that the getline or the ">>" would get rid of that one as well. – AzP Oct 18 '17 at 17:03
31
#include <iostream>
#include <sstream>
#include <string>
using namespace std;

int main()
{
    string str("123 abc");
    int a;
    istringstream is(str);
    is >> a;

    // here we extract a copy of the "remainder"
    string rem(is.str().substr(is.tellg()));

    cout << "Remaining: [" << rem << "]\n";
}
Leo Heinsaar
  • 3,887
  • 3
  • 15
  • 35
Jnana
  • 824
  • 13
  • 12
9
std::istringstream input;
int extracted;
input >> extracted;

IMO, the simplest thing you could possibly do is this:

std::stringstream tmp;
tmp << input.rdbuf();
std::string remainder = tmp.str();

This is not optimal in terms of performance. Otherwise, directly access the stringbuffer (probably using rbuf().pubseekpos and tellg on the stream... haven't tested that).

sehe
  • 374,641
  • 47
  • 450
  • 633
  • So the `rdbuf()` stores the remaining string? – draw Jun 08 '11 at 23:20
  • rdbuf() _implements_ the buffer for the stream; I believe stores all the data including the already-extracted data. Now, `operator<<` for a `streambuf` is defined in such a way, that it will _do the right thing_ without you having to worry about the stream position. – sehe Jun 08 '11 at 23:21
4

std::getline

getline reads characters from an input stream and places them into a string

Nimantha
  • 6,405
  • 6
  • 28
  • 69
Cheers and hth. - Alf
  • 142,714
  • 15
  • 209
  • 331
3

Alternatively, if you need the rest of the string verbatim you can use std::getline(my_stringstream, result, EOF) where result is a std::string containing the result.

EdF
  • 549
  • 3
  • 12
  • The delimiter can only be a char, and a the actual EOF is not exposed to `getline`, so it will be interpreted as the char `\xff` (the macro EOF is defined as `(-1)`). It would only seem to work if that character is not present in the string. – alexisdm Aug 31 '13 at 22:56
1

Keep using operator>>, it will extract the rest of it in whitespace-delimited pieces.

Puppy
  • 144,682
  • 38
  • 256
  • 465
  • my concern is that I want to leave the white spaces in the remaining string, I'm trying to use substring – draw Jun 08 '11 at 23:17