tags:

views:

119

answers:

3

I've seen people do things like....

 istringstream ibuf;

 if (ibuf >>  zork >> iA >> Comma >> iB)

now I guess the value depends on what >>iB exposes but exactly what is that and what does it mean? Does true mean all the ietms were extracted?

Also, after an expression like

 ibuf >>  zork >> iA >> Comma >> iB;

is there any way to find out how many characters and items where extracted?

+1  A: 

The second piece of code reads a set of values from the ibuf to the variables following it. However, the return of the hidden operator >>() call is an istringstream object. There's no direct way to get the character count.

You can check out the gcount member function which gives the number of characters for the last unformatted input operation. Note that this is per operation, so cascading can't be used. You can also use the read member function.

Edit:

(ibuf >>  zork >> iA >> Comma >> iB)

is actually:

((((ibuf.operator >>(zork)).operator >>(iA)).operator >>(Comma)).operator >>(iB))

The nesting level of parenthesis tell you the order of calls (and the arguments).

dirkgently
@dirkgently: Can you tell me more about the "hidden operator"? Maybe expand my example into a complete parenthesis and show it?
Mike D
@Mike D: updated answer.
dirkgently
+1  A: 

This works because of two properties of istream objects:

  • istreams return themselves after each extraction (the >> operator) to allow chaining multiple extractions (a >> b >> c)
  • istreams return their status (as though .good() were called) when they're cast/converted to bool, via overloading bool operator !()

Basically the code you wrote is a short-hand version of:

if ( ((((ibuf >> zork) >> ia) >> Comma) >> ib).good() ) {

}

Once all the extractions have occured, you're left with if (ibuf) which is implicitly like writing if ((bool)ibuf), which checks ibuf.good().

There is no way to get the number of characters extracted over a series of chained extractions, but you can find the number of characters extracted during the last operation with the function gcount. However, it only works for certain format-ignoring functions like get and getline, and not the extraction operator.

meagar
This is not a cast but an implicit type conversion. Minor nit.
dirkgently
Is there a technical difference between an "implicit cast" and "implicit conversion"? Does one imply something the other doesn't?
meagar
If I'm reading http://www.cplusplus.com/reference/iostream/istream/ correctly it's operator! and operator void* not operator bool. The end result is the same though.
Mark B
@Mark Thanks, fixed.
meagar
`bool(stream)` is the same as `!stream.fail()`, which is *different* from `stream.good()`!
Roger Pate
+1  A: 
if (ibuf >>  zork >> iA >> Comma >> iB)

is logically equal to:

ibuf >> zork;
ibuf >> iA;
ibuf >> Comma;
ibuf >> iB;
if (ibuf) ...

"is there any way to find out how many characters and items where extracted?"

There is member function "gcount": http://www.cplusplus.com/reference/iostream/istream/gcount/

neverlord
No, checking `.good()` is not cleaner and actually behaves differently. Use `if (ibuf)` in the above code.
Roger Pate
You're right..good() does only check for error flags (edited).
neverlord
@neverlord: You can use the @-syntax so I know you've replied to me, and in this case change the vote; but I happened back here anyway this time. :)
Roger Pate
@Roger Pate: I'm going to remember this. :)
neverlord