cin error recovery | | |
Have following snippet:
int i1, i2;
cin >> i1;
cin >> i2;
cout << i1 << ", " << i2;
If on first prompt I enter non-numeric value, then second value is not
prompted and i1, i2 are set to some weird value.
Q: is there something I can do to be able to enter second value even
if first value was invalid?
Note: cin.clear() - does not help.
Note: cin.clear() does help under Windows (WinXP), but does not work
under SunOS (5.2)
Thank you,
Regards,
Roman | | | | re: cin error recovery
"Roman Gavrilov" <clavrg@hotmail.com> wrote in message
news:fe75986a.0402071558.a4cc4e0@posting.google.co m...[color=blue]
> Have following snippet:
>
> int i1, i2;
> cin >> i1;
> cin >> i2;
> cout << i1 << ", " << i2;
>
> If on first prompt I enter non-numeric value, then second value is[/color]
not[color=blue]
> prompted and i1, i2 are set to some weird value.
>
> Q: is there something I can do to be able to enter second value even
> if first value was invalid?
>[/color]
Did you trying clearing the error state, then reading and discarding
the remainder of the line? E.g.
if (!(cin >> i1)) {
cin.clear();
std::string s;
cin >> s;
cout << "Did I tell you to write " << s << "?\n";
cout << "I said, input a *number*, stupid!\n";
}
Jonathan | | | | re: cin error recovery
In article <fe75986a.0402071558.a4cc4e0@posting.google.com> ,
Roman Gavrilov <clavrg@hotmail.com> wrote:[color=blue]
>Have following snippet:
>
>int i1, i2;
>cin >> i1;
>cin >> i2;
>cout << i1 << ", " << i2;
>
>If on first prompt I enter non-numeric value, then second value is not
>prompted and i1, i2 are set to some weird value.
>
>Note: cin.clear() - does not help.[/color]
Actually, cin.clear() *does* help, but it's not all you need to do.
When stream input encounters an illegal character, input stops at that
character, leaving it in the input stream so you can try to read it a
different way if you want. In your case, you probably want to skip past
it to the next hopefully valid input item.
cin.clear() resets the stream status flags, which allows further input to
take place, but it doesn't actually move the input point in the file. So
if you try to read again, you just hit the bad data again.
One common way to skip past the bad data is to assume that the items are
separated by newlines, and use something like cin.ignore(1000, '\n') which
skips to just past the next newline, or 1000 chars, whichever comes first.
This works better if you prompt for the two numbers separately so they
have to be on separate lines.
If the two numbers are supposed to be on the same line, you could probably
simply read the bad data into a dummy string using >>, which will read
until the next whitespace; then try to read the next number normally.
--
Jon Bell <jtbellm4h@presby.edu> Presbyterian College
Dept. of Physics and Computer Science Clinton, South Carolina USA | | | | re: cin error recovery
My bad, full text would be:
int i1, i2;
cin >> i1;
cin.clear();
cin.ignore(cin.rdbuf()->in_avail());
cin >> i2;
cout << i1 << " " << i2 << endl;
so, I do clear the rest of the input buffer. Problem goes even deaper - does
not matter how many times after the error I try to read cin - it always
returns an error.
while (true) {
int i1;
cin >> i1;
cout << i1;
}
if in the snippet above I enter error once, it will output the "weird" value
forever.
Regards,
Roman
"Jon Bell" <jtbellj3p@presby.edu> wrote in message
news:c047jb$svv$1@jtbell.presby.edu...[color=blue]
> In article <fe75986a.0402071558.a4cc4e0@posting.google.com> ,
> Roman Gavrilov <clavrg@hotmail.com> wrote:[color=green]
> >Have following snippet:
> >
> >int i1, i2;
> >cin >> i1;
> >cin >> i2;
> >cout << i1 << ", " << i2;
> >
> >If on first prompt I enter non-numeric value, then second value is not
> >prompted and i1, i2 are set to some weird value.
> >
> >Note: cin.clear() - does not help.[/color]
>
> Actually, cin.clear() *does* help, but it's not all you need to do.
>
> When stream input encounters an illegal character, input stops at that
> character, leaving it in the input stream so you can try to read it a
> different way if you want. In your case, you probably want to skip past
> it to the next hopefully valid input item.
>
> cin.clear() resets the stream status flags, which allows further input to
> take place, but it doesn't actually move the input point in the file. So
> if you try to read again, you just hit the bad data again.
>
> One common way to skip past the bad data is to assume that the items are
> separated by newlines, and use something like cin.ignore(1000, '\n') which
> skips to just past the next newline, or 1000 chars, whichever comes first.
> This works better if you prompt for the two numbers separately so they
> have to be on separate lines.
>
> If the two numbers are supposed to be on the same line, you could probably
> simply read the bad data into a dummy string using >>, which will read
> until the next whitespace; then try to read the next number normally.
>
> --
> Jon Bell <jtbellm4h@presby.edu> Presbyterian College
> Dept. of Physics and Computer Science Clinton, South Carolina USA[/color] | | | | re: cin error recovery
"Roman Gavrilov" <clavrg@hotmail.com> wrote in message
news:8bSdnRQOJeiGULjdRVn-gg@comcast.com...[color=blue]
> My bad, full text would be:
>
> int i1, i2;
> cin >> i1;
> cin.clear();
> cin.ignore(cin.rdbuf()->in_avail());
> cin >> i2;
> cout << i1 << " " << i2 << endl;
>
> so, I do clear the rest of the input buffer. Problem goes even[/color]
deaper - does[color=blue]
> not matter how many times after the error I try to read cin - it[/color]
always[color=blue]
> returns an error.
>[/color]
What compiler/standard library are you using?
Jonathan | | | | re: cin error recovery
Roman Gavrilov wrote:
[color=blue]
>
> while (true) {
> int i1;
> cin >> i1;
> cout << i1;
> }
>
> if in the snippet above
> I enter error once, it will output the "weird" value forever.[/color]
Of course. That's what it's supposed to do. Try this:
[color=blue]
> cat main.cc[/color]
#include <iostream>
int main(int argc, char* argv[]) {
int i1 = 666;
while (std::cin >> i1) {
std::cout << i1 << std::endl;
}
std::cout << i1 << std::endl;
return 0;
}
[color=blue]
> g++ -Wall -ansi -pedantic -o main main.cc
> ./main[/color]
www
666[color=blue]
> ./main[/color]
777
777
www
777
The input function
istream& operator>>(istream&, int&)
looks at the first character of "www" and knows that
it can't be part of an int so it returns with i1 unchanged.
It doesn't actually read any characters so "www"
will still be there the next time that you try to read.
Notice that if I enter 777 operator>> succeeds
and i1 is set to 777. | | | | re: cin error recovery
On Sat, 7 Feb 2004 21:45:41 -0800 in comp.lang.c++, "Roman Gavrilov"
<clavrg@hotmail.com> was alleged to have written:[color=blue]
>cin.clear();
>cin.ignore(cin.rdbuf()->in_avail());[/color]
in_avail() is probably not useful for this purpose (maybe any purpose.)
Suggest you try our instead:
std::cin.ignore(std::numeric_limits<std::streamsiz e>::max(), '\n'); | | | | re: cin error recovery
David,
Thank you, you were right - in_avail was returning a 0.
Works now as expected
Regards,
Roman
David Harmon <source@netcom.com> wrote in message news:<40472dfd.78975162@news.west.earthlink.net>.. .[color=blue]
> On Sat, 7 Feb 2004 21:45:41 -0800 in comp.lang.c++, "Roman Gavrilov"
> <clavrg@hotmail.com> was alleged to have written:[color=green]
> >cin.clear();
> >cin.ignore(cin.rdbuf()->in_avail());[/color]
>
> in_avail() is probably not useful for this purpose (maybe any purpose.)
>
> Suggest you try our instead:
> std::cin.ignore(std::numeric_limits<std::streamsiz e>::max(), '\n');[/color] |  | | | | /bytes/about
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 226,392 network members.
|