stringstream Problems

M

Mike Copeland

I am trying to use stringstreams to parse some complex data. In the
code below, myTest is a string that contains int (9), char ('M'),
string ("45-49") and
string (" Male Age Group 45-49") data fields, and I can't get the
code to work. Perhaps there's an option to set or function to call, but
I'm lost here. Please advise. TIA

stringstream sss;
string myTest = "9 M45-49 Male Age Group 45-49 ";
string s1, s2;
int i1;
char c1;
sss.str(myTest);
sss >> i1 >> c1 >> setw(5) >> s1 >> setw(40) >> s2;
 
C

Christopher Pisz

I am trying to use stringstreams to parse some complex data. In the
code below, myTest is a string that contains int (9), char ('M'),
string ("45-49") and
string (" Male Age Group 45-49") data fields, and I can't get the
code to work. Perhaps there's an option to set or function to call, but
I'm lost here. Please advise. TIA

stringstream sss;
string myTest = "9 M45-49 Male Age Group 45-49 ";
string s1, s2;
int i1;
char c1;
sss.str(myTest);
sss >> i1 >> c1 >> setw(5) >> s1 >> setw(40) >> s2;

You seem to be confused about when separates a token in a stream and how
setw works.

Every time you attempt to extract something from a stream, it will
extract text up to the first space character it encounters, by default.
It then _attempts_ to transform that sequence of characters into the
type you are requesting, if an operator for it is defined. If the
transformation fails, the fail bit will be set, you need to check for
that on every extraction.

if( (mystream >> myint).fail() )
{
// could not convert token to int
}

In your example above, you have 6 tokens
You attempt to extract 4. Start with that problem.
 
M

Mike Copeland

You seem to be confused about when separates a token in a stream and how
setw works.

Every time you attempt to extract something from a stream, it will
extract text up to the first space character it encounters, by default.
It then _attempts_ to transform that sequence of characters into the
type you are requesting, if an operator for it is defined. If the
transformation fails, the fail bit will be set, you need to check for
that on every extraction.

if( (mystream >> myint).fail() )
{
// could not convert token to int
}

In your example above, you have 6 tokens
You attempt to extract 4. Start with that problem.

Actually, you've helped. The characteristic of space-delimitation is
a "deal-killer" for me, because what follows the 3rd token can't be
predicted. Yes, in my example there are 6 "tokens", but I want to treat
everything after the 4th token as a single (string) token. With these
constructs, the stringstream technique won't work for me. 8<{{
Thanks for the help, though...
 
G

Gert-Jan de Vos

I am trying to use stringstreams to parse some complex data. In the
code below, myTest is a string that contains int (9), char ('M'),
string ("45-49") and
string (" Male Age Group 45-49") data fields, and I can't get the
code to work. Perhaps there's an option to set or function to call, but
I'm lost here. Please advise. TIA

stringstream sss;
string myTest = "9 M45-49 Male Age Group 45-49 ";
string s1, s2;
int i1;
char c1;
sss.str(myTest);
sss >> i1 >> c1 >> setw(5) >> s1 >> setw(40) >> s2;

Reading a string from an input stream is always white space
delimited. If the only string containing white space is the
last part of the line you can use std::getline() like this:

std::stringstream ss("9 M45-49 Male Age Group 45-49 ");
std::string s1, s2;
int i1;
char c1;

if (ss >> i1 >> c1 >> s1 && std::getline(ss, s2))
std::cout <<
"(" << i1 << ")" <<
"(" << c1 << ")" <<
"(" << s1 << ")" <<
"(" << s2 << ")" << "\n";

You may want to have a look at using regex to handle more
complex input data.
 
B

Bart van Ingen Schenau

That is not true. Conceptually, the stream extraction operators (>>) read
*one* character ahead to see if that could still be be part of the type
you are trying to read. In this process, leading whitespace before a
value are always considered acceptable and are silently discarded.
operator>>(istream, string) is a bit special, because it considers a
whitespace character (other than the leading whitespace) to be
inappropriate for storing in a string.

Combined, this results in the apparent behaviour that values should be
separated by spaces (which is only strictly needed for values of
sufficiently similar types) and that only single words can be read into a
string.
Actually, you've helped. The characteristic of space-delimitation is
a "deal-killer" for me, because what follows the 3rd token can't be
predicted. Yes, in my example there are 6 "tokens", but I want to treat
everything after the 4th token as a single (string) token. With these
constructs, the stringstream technique won't work for me. 8<{{
Thanks for the help, though...

As most of the spaces in your example string are in the right positions,
you can parse it with a combination of operator>> and getline:

stringstream sss;
string myTest = "9 M45-49 Male Age Group 45-49 ";
string s1, s2;
int i1;
char c1;
sss.str(myTest);
sss >> i1 >> c1 >> s1;
getline(sss, s2);

Bart v Ingen Schenau
 
C

Christopher Pisz

Actually, you've helped. The characteristic of space-delimitation is
a "deal-killer" for me, because what follows the 3rd token can't be
predicted. Yes, in my example there are 6 "tokens", but I want to treat
everything after the 4th token as a single (string) token. With these
constructs, the stringstream technique won't work for me. 8<{{
Thanks for the help, though...

Well, stringstream cannot be psychic. Something has to signify the
separation. Since the same character that defines the separation is part
of the data, you need to use a different character to define the
separation. Say, a comma for example. Then use istream::getline with the
delimiter argument.

You could also use the gcount, peek, read, seekg, etc. methods if you
wanted to define some protocol where each field has a specified number
of characters, but you will have to put them in that way too.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top