|
Prev: weird static cast
Next: Union's
From: Ulrich Eckhardt on 6 Jul 2006 06:33 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 7 Jul 2006 10:10 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 9 Jul 2006 17:06 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 9 Jul 2006 17:07 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 10 Jul 2006 17:36 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 |