[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

Simple stringstream question

Fencer

10/10/2008 7:41:00 PM

Hi!

Say I have string of the following form:
"integer stringpart". First an integer, then a space and then the
stringpart which may or may not contain additional spaces. I wanted to
separate the integer and the stringpart, so I tried:

istringstream iss(str);

int num;

iss >> num;

Ok, now num contains the int-part. But how do I get the rest into a
string variable? iss.str() returns the entire string and iss >>
astrinvar; only gets me a subpart if the stringpart contains spaces
Is a loop my only option here or have I missed something?

- WP
7 Answers

Victor Bazarov

10/10/2008 8:02:00 PM

0

WP wrote:
> Say I have string of the following form:
> "integer stringpart". First an integer, then a space and then the
> stringpart which may or may not contain additional spaces. I wanted to
> separate the integer and the stringpart, so I tried:
>
> istringstream iss(str);
>
> int num;
>
> iss >> num;
>
> Ok, now num contains the int-part. But how do I get the rest into a
> string variable? iss.str() returns the entire string and iss >>
> astrinvar; only gets me a subpart if the stringpart contains spaces
> Is a loop my only option here or have I missed something?

You can always get the remaining part of the stringstream by reading its
'streambuf', I think:

#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";
}

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

Rolf Magnus

10/10/2008 8:39:00 PM

0

Victor Bazarov wrote:

> WP wrote:
>> Say I have string of the following form:
>> "integer stringpart". First an integer, then a space and then the
>> stringpart which may or may not contain additional spaces. I wanted to
>> separate the integer and the stringpart, so I tried:
>>
>> istringstream iss(str);
>>
>> int num;
>>
>> iss >> num;
>>
>> Ok, now num contains the int-part. But how do I get the rest into a
>> string variable? iss.str() returns the entire string and iss >>
>> astrinvar; only gets me a subpart if the stringpart contains spaces
>> Is a loop my only option here or have I missed something?
>
> You can always get the remaining part of the stringstream by reading its
> 'streambuf', I think:
>
> #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()));

Hmm, is the above line guaranteed to work correctly? I mean mixing string
positions and stream positions.

>
> cout << "Remaining: [" << rem << "]\n";
> }

Alternativeley, split the stream up before converting the number:

string str("123 Hello World");
string::size_type pos = str.find(' ');
string first = str.substr(0, pos);
string second = str.substr(pos + 1, string::npos);

Then you can use the stringstream to convert the number.

James Kanze

10/10/2008 9:06:00 PM

0

On Oct 10, 10:02 pm, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
> WP wrote:
> > Say I have string of the following form:
> > "integer stringpart". First an integer, then a space and
> > then the stringpart which may or may not contain additional
> > spaces. I wanted to separate the integer and the stringpart,
> > so I tried:

> > istringstream iss(str);

> > int num;

> > iss >> num;

> > Ok, now num contains the int-part. But how do I get the rest
> > into a string variable? iss.str() returns the entire string
> > and iss >> astrinvar; only gets me a subpart if the
> > stringpart contains spaces Is a loop my only option here or
> > have I missed something?

> You can always get the remaining part of the stringstream by
> reading its 'streambuf', I think:

That would be the a solution, I think, if you don't know a
character that can't be in the string. If you know that there's
no newline, however, getline will also work; if there is no
further white space, >> into a string is fine.

> #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()));

That's not what you said above, and I'm not sure what it will
give. Calling istringstream::str() seems very strange to me.
I'd prefer something like:

std::string remaining ;
is >> remaining ; // skips white space, stops at next
// following whitespace.
std::getline( is, remaining ) ;
// reads until next '\n'
std::ostringstream os ;
os << is.rdbuf() ; // gets absolutely everything.

Don't forget that istream::tellg() isn't guaranteed to be
convertible into an integral type, and even if it is, there is
no guarantee concerning the numeric value.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

James Kanze

10/10/2008 9:07:00 PM

0

On Oct 10, 10:39 pm, Rolf Magnus <ramag...@t-online.de> wrote:

[...]
> Alternativeley, split the stream up before converting the number:

>     string str("123 Hello World");
>     string::size_type pos = str.find(' ');
>     string first = str.substr(0, pos);
>     string second = str.substr(pos + 1, string::npos);

> Then you can use the stringstream to convert the number.

The splitting is a lot easier, and a lot more robust, if you use
boost::regex to do it.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Victor Bazarov

10/10/2008 9:08:00 PM

0

Rolf Magnus wrote:
> [..]

I don't know if stream_pos and size_type can be mixed. I think it has
to be close since the underlying buffer of the string stream *is* a
string, after all.

> Alternativeley, split the stream up before converting the number:
>
> string str("123 Hello World");
> string::size_type pos = str.find(' ');
> string first = str.substr(0, pos);
> string second = str.substr(pos + 1, string::npos);
>
> Then you can use the stringstream to convert the number.

Well, don't just look for spaces, mate. You need to look for any
non-digit. The string "123abc" doesn't have a space, yet the integer
you can read from it is the same as from "123 Hello World"...

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

Victor Bazarov

10/10/2008 9:18:00 PM

0

James Kanze wrote:
> On Oct 10, 10:02 pm, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
>> WP wrote:
>>> Say I have string of the following form:
>>> "integer stringpart". First an integer, then a space and
>>> then the stringpart which may or may not contain additional
>>> spaces. I wanted to separate the integer and the stringpart,
>>> so I tried:
>
>>> istringstream iss(str);
>
>>> int num;
>
>>> iss >> num;
>
>>> Ok, now num contains the int-part. But how do I get the rest
>>> into a string variable? iss.str() returns the entire string
>>> and iss >> astrinvar; only gets me a subpart if the
>>> stringpart contains spaces Is a loop my only option here or
>>> have I missed something?
>
>> You can always get the remaining part of the stringstream by
>> reading its 'streambuf', I think:
>
> That would be the a solution, I think, if you don't know a
> character that can't be in the string. If you know that there's
> no newline, however, getline will also work; if there is no
> further white space, >> into a string is fine.
>
>> #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()));
>
> That's not what you said above, and I'm not sure what it will
> give. [..]

Yeah, well, I started by looking at how to get the stringbuf, and then
the substr approach with is.str() seemed easier, so I gave up on the
buffer thing...

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

Rolf Magnus

10/11/2008 4:20:00 AM

0

Victor Bazarov wrote:

> Rolf Magnus wrote:
>> [..]
>
> I don't know if stream_pos and size_type can be mixed. I think it has
> to be close since the underlying buffer of the string stream *is* a
> string, after all.
>
>> Alternativeley, split the stream up before converting the number:
>>
>> string str("123 Hello World");
>> string::size_type pos = str.find(' ');
>> string first = str.substr(0, pos);
>> string second = str.substr(pos + 1, string::npos);
>>
>> Then you can use the stringstream to convert the number.
>
> Well, don't just look for spaces, mate. You need to look for any
> non-digit. The string "123abc" doesn't have a space, yet the integer
> you can read from it is the same as from "123 Hello World"...

Well, but that wasn't the OP's specification, according to which there is
always a space between the number and the rest. Of course, format error
handling is missing in my code, but that's the same in your code.