31

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.

ネロク
  • 21,268
  • 3
  • 51
  • 67
draw
  • 4,526
  • 6
  • 28
  • 36

6 Answers6

40

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
  • 341,464
  • 111
  • 648
  • 831
  • @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
  • 4
    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
28
#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";
}
Lmn
  • 3,737
  • 3
  • 14
  • 32
Jnana
  • 713
  • 11
  • 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
  • 350,152
  • 45
  • 431
  • 590
  • 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< – sehe Jun 08 '11 at 23:21
4

std::getline

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

Nimantha
  • 5,793
  • 5
  • 23
  • 56
Cheers and hth. - Alf
  • 138,963
  • 15
  • 198
  • 315
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
  • 11
  • 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
  • 141,834
  • 35
  • 244
  • 454
  • 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