From: Ulrich Eckhardt on
Hi!

I'm parsing some text with a stringstream and came across something that
struck me as odd. I'm testing if a string contains a number (surrounded by
optional whitespace) and different stdlibs behave differently.

unsigned n;
in >> std::ws >> n >> std::ws;
if( !in.fail() && in.eof())
...//it's a number

Using "10" as input, the problem I have is that after the unsigned value is
read the streamstate is eof. The following '>> std::ws' then causes the
streamstate to be fail|eof, at least with some implementations.

My prerelease copy of the standard says explicitly that ws sets eofbit but
not failbit if no more characters are available, but it doesn't explicitly
mention what happens when the eofbit is already set when it is invoked.

My guess is that it should detect eofbit and and simply return instead of
setting failbit, but I'd like to clarify that.

Uli


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: jbannon on
Ulrich Eckhardt wrote:
> Hi!
>
> I'm parsing some text with a stringstream and came across something that
> struck me as odd. I'm testing if a string contains a number (surrounded by
> optional whitespace) and different stdlibs behave differently.
>
> unsigned n;
> in >> std::ws >> n >> std::ws;
> if( !in.fail() && in.eof())
> ...//it's a number
>
> Using "10" as input, the problem I have is that after the unsigned value is
> read the streamstate is eof. The following '>> std::ws' then causes the
> streamstate to be fail|eof, at least with some implementations.
>
> My prerelease copy of the standard says explicitly that ws sets eofbit but
> not failbit if no more characters are available, but it doesn't explicitly
> mention what happens when the eofbit is already set when it is invoked.
>
> My guess is that it should detect eofbit and and simply return instead of
> setting failbit, but I'd like to clarify that.

Is this what you mean?

Clause 27.6.1.2.3 basic_istream::operator>> paragraph 8:

"If the function extracted no characters, it calls setstate(failbit),
which may throw ios_base::failure (27.4.4.3)"

If the stream state is already at eof then this would seem to indicate
that the failbit is set so that the state of the stream would be
failbit|eof as in your implementation.

Best regards
Jim Bannon.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: James Kanze on
Ulrich Eckhardt wrote:

> I'm parsing some text with a stringstream and came across
> something that struck me as odd. I'm testing if a string
> contains a number (surrounded by optional whitespace) and
> different stdlibs behave differently.

> unsigned n;
> in >> std::ws >> n >> std::ws;
> if( !in.fail() && in.eof())
> ...//it's a number

Just a nit, but the first >> std::ws isn't necessary.

> Using "10" as input, the problem I have is that after the
> unsigned value is read the streamstate is eof. The following
> '>> std::ws' then causes the streamstate to be fail|eof, at
> least with some implementations.

> My prerelease copy of the standard says explicitly that ws
> sets eofbit but not failbit if no more characters are
> available, but it doesn't explicitly mention what happens when
> the eofbit is already set when it is invoked.

> My guess is that it should detect eofbit and and simply return
> instead of setting failbit, but I'd like to clarify that.

I'd say that that is certainly the intent. I can't see any
other way of reading ?27.6.1.4/1.

What is probably happening is that a sentry object is being
constructed. Strictly speaking, I don't see anything to forbid
this, although I don't think it corresponds to the intent of
manipulators. (Note that in this case, the >> operator is NOT
formatted input, which should fail if eosbit is set on entry.)

Just out of curiousity, could you indicate on which compilers it
fails. I use the idiom a lot, and I've never had any problem
(but I don't use a large variety of different compilers in my
current work).

--
James Kanze kanze.james(a)neuf.fr
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

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: James Kanze on
jbannon wrote:

>> My guess is that it should detect eofbit and and simply
>> return instead of setting failbit, but I'd like to clarify
>> that.

> Is this what you mean?

> Clause 27.6.1.2.3 basic_istream::operator>> paragraph 8:

> "If the function extracted no characters, it calls
> setstate(failbit), which may throw ios_base::failure
> (27.4.4.3)"

> If the stream state is already at eof then this would seem to
> indicate that the failbit is set so that the state of the
> stream would be failbit|eof as in your implementation.

This paragraph explicitly only applies to formatted input
functions. std::ws is a manipulator, so the operator>> here is
not a formatted input function (and the paragraph doesn't
apply).

--
James Kanze kanze.james(a)neuf.fr
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

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Ulrich Eckhardt on
James Kanze wrote:
> Ulrich Eckhardt wrote:
>> I'm parsing some text with a stringstream and came across
>> something that struck me as odd. I'm testing if a string
>> contains a number (surrounded by optional whitespace) and
>> different stdlibs behave differently.
>>
>> unsigned n;
>> in >> std::ws >> n >> std::ws;
>> if( !in.fail() && in.eof())
>> ...//it's a number
>
> Just a nit, but the first >> std::ws isn't necessary.

Yes, true, leaving aside that one might have reset the skipws flag. I just
put that in to demonstrate the different behaviours - in both cases the
std::ws effectively does the same, but in one case it sets failbit only
because eofbit is set.

>> Using "10" as input, the problem I have is that after the
>> unsigned value is read the streamstate is eof. The following
>> '>> std::ws' then causes the streamstate to be fail|eof, at
>> least with some implementations.
>>
>> My prerelease copy of the standard says explicitly that ws
>> sets eofbit but not failbit if no more characters are
>> available, but it doesn't explicitly mention what happens when
>> the eofbit is already set when it is invoked.
>>
>> My guess is that it should detect eofbit and and simply return
>> instead of setting failbit, but I'd like to clarify that.
>
> I'd say that that is certainly the intent. I can't see any
> other way of reading ?27.6.1.4/1.
>
> What is probably happening is that a sentry object is being
> constructed. Strictly speaking, I don't see anything to forbid
> this, although I don't think it corresponds to the intent of
> manipulators. (Note that in this case, the >> operator is NOT
> formatted input, which should fail if eosbit is set on entry.)

Good guess! A sentry is indeed being constructed.

> Just out of curiousity, could you indicate on which compilers it
> fails. I use the idiom a lot, and I've never had any problem
> (but I don't use a large variety of different compilers in my
> current work).

Nothing released yet, I found that this fails with the STLport 5.1
prerelease. AFAICT, it didn't fail with the released 5.0 versions and
surely not with 4.x versions, so there is a chance that you will never see
something like above behaviour in the open. In fact I'm trying to harvest
arguments here, since I couldn't extract a mandatory behaviour from the
standard.

Uli


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

 | 
Pages: 1
Prev: weird static cast
Next: Union's