Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Verifying valid input in a loop

Reply
Thread Tools

Verifying valid input in a loop

 
 
JR
Guest
Posts: n/a
 
      09-11-2004
Hey all,

I have read part seven of the FAQ and searched for an answer but can
not seem to find one.

I am trying to do the all too common verify the data type with CIN.
The code from the FAQ looks like this:

#include <iostream>

int main()
{
std::cout << "Enter a number, or -1 to quit: ";
int i = 0;
while (std::cin >> i) { // GOOD FORM
if (i == -1) break;
std::cout << "You entered " << i << '\n';
}
}


This works well except that I do not want to exit the loop unless a
valid input is entered. So if I enter an 'a' I want to stay in the
loop to allow for another chance at input not exit the loop. Can
someone please provide a modified version of this code that will allow
this?


Thanks,

James
 
Reply With Quote
 
 
 
 
John Harrison
Guest
Posts: n/a
 
      09-11-2004

"JR" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) om...
> Hey all,
>
> I have read part seven of the FAQ and searched for an answer but can
> not seem to find one.
>
> I am trying to do the all too common verify the data type with CIN.
> The code from the FAQ looks like this:
>
> #include <iostream>
>
> int main()
> {
> std::cout << "Enter a number, or -1 to quit: ";
> int i = 0;
> while (std::cin >> i) { // GOOD FORM
> if (i == -1) break;
> std::cout << "You entered " << i << '\n';
> }
> }
>
>
> This works well except that I do not want to exit the loop unless a
> valid input is entered. So if I enter an 'a' I want to stay in the
> loop to allow for another chance at input not exit the loop. Can
> someone please provide a modified version of this code that will allow
> this?
>


It's difficult to validate input, it gets very fiddly. C++ cannot provide a
standard solution because what is valid input for one program is not valid
for another. And since you don't say what is valid input for your program
its impossible to give a detailed answer. I would guess that only positive
integers and -1 are valid for you.

However the general approach is simple enough. Read the input as a string,
check to see if the string is a valid number (whatever that means for your
program) and only then convert the string to an integer.

John


 
Reply With Quote
 
 
 
 
osmium
Guest
Posts: n/a
 
      09-11-2004
JR writes:

> I am trying to do the all too common verify the data type with CIN.
> The code from the FAQ looks like this:
>
> #include <iostream>
>
> int main()
> {
> std::cout << "Enter a number, or -1 to quit: ";
> int i = 0;
> while (std::cin >> i) { // GOOD FORM
> if (i == -1) break;
> std::cout << "You entered " << i << '\n';
> }
> }
>
>
> This works well except that I do not want to exit the loop unless a
> valid input is entered. So if I enter an 'a' I want to stay in the
> loop to allow for another chance at input not exit the loop. Can
> someone please provide a modified version of this code that will allow
> this?


The overloaded >> specifies conversion. There is no back door way to get
the faulty input (for example, a letter), the stream goes into a fail state
if it gets bad input. So base your solution on getline() and do the
conversion "manually". Also, see ios::fail() and ios::clear(). The
simplest conversion would probably be strtol() in cstdlib. Using the stuff
in the iostreams package would be more elegant, but IMO harder.

You would have to give up the ability to display the faulty input to the
user if you wanted to persist in using cin.


 
Reply With Quote
 
Jon Bell
Guest
Posts: n/a
 
      09-11-2004
In article <(E-Mail Removed) >,
JR <(E-Mail Removed)> wrote:
>
>#include <iostream>
>
> int main()
> {
> std::cout << "Enter a number, or -1 to quit: ";
> int i = 0;
> while (std::cin >> i) { // GOOD FORM
> if (i == -1) break;
> std::cout << "You entered " << i << '\n';
> }
> }
>
>
>This works well except that I do not want to exit the loop unless a
>valid input is entered. So if I enter an 'a' I want to stay in the
>loop to allow for another chance at input not exit the loop. Can
>someone please provide a modified version of this code that will allow
>this?


First, let's just do the error checking for a single input, and not worry
about the "-1 to quit" yet:

int i;
cout << "Please enter an integer, and press ENTER: ";
while (! (cin >> i))
{
cin.clear(); // reset stream status flags
cin.ignore(1000,'\n'); // skip past next newline (ENTER), or 1000
// chars, whichever comes first
cout << "Hey dummy, I said enter an integer! Try again: ";
}

If you want to input repeatedly until the user enters -1, wrap this in
another loop that tests for end of data:

int i = 0;
while (i != -1)
{
cout << "Please enter an integer, and press ENTER: ";
while (! (cin >> i))
{
cin.clear();
cin.ignore(1000,'\n');
cout << "Hey dummy, I said enter an integer! Try again: ";
}
if (i != -1)
{
// process i normally
}
}

Or you can make the real processing-code a bit cleaner by writing a
function to do the input and error-checking:

bool GetNumber (int& num)
{
cout << "Please enter an integer, and press ENTER: ";
while (! (cin >> num))
{
cin.clear();
cin.ignore(1000,'\n');
cout << "Hey dummy, I said enter an integer! Try again: ";
}
return (num != -1); // returns true if not at end of input yet
}

// the real processing-code

int i;
while (GetNumber(i))
{
// process i normally
}

--
Jon Bell <(E-Mail Removed)> Presbyterian College
Dept. of Physics and Computer Science Clinton, South Carolina USA
 
Reply With Quote
 
JR
Guest
Posts: n/a
 
      09-12-2004
http://www.velocityreviews.com/forums/(E-Mail Removed) (Jon Bell) wrote in message news:<chvsup$hql$(E-Mail Removed)>...
<snip>>

First, let's just do the error checking for a single input, and not
worry
> about the "-1 to quit" yet:
>
> int i;
> cout << "Please enter an integer, and press ENTER: ";
> while (! (cin >> i))
> {
> cin.clear(); // reset stream status flags
> cin.ignore(1000,'\n'); // skip past next newline (ENTER), or 1000
> // chars, whichever comes first
> cout << "Hey dummy, I said enter an integer! Try again: ";
> }
>
> If you want to input repeatedly until the user enters -1, wrap this in
> another loop that tests for end of data:
>
> int i = 0;
> while (i != -1)
> {
> cout << "Please enter an integer, and press ENTER: ";
> while (! (cin >> i))
> {
> cin.clear();
> cin.ignore(1000,'\n');
> cout << "Hey dummy, I said enter an integer! Try again: ";
> }
> if (i != -1)
> {
> // process i normally
> }
> }
>
> Or you can make the real processing-code a bit cleaner by writing a
> function to do the input and error-checking:
>
> bool GetNumber (int& num)
> {
> cout << "Please enter an integer, and press ENTER: ";
> while (! (cin >> num))
> {
> cin.clear();
> cin.ignore(1000,'\n');
> cout << "Hey dummy, I said enter an integer! Try again: ";
> }
> return (num != -1); // returns true if not at end of input yet
> }
>
> // the real processing-code
>
> int i;
> while (GetNumber(i))
> {
> // process i normally
> }


Thanks All,

Jon I really like your solution. I came across is a couple hours
after I posted in this post .

http://groups.google.com/groups?hl=e...ng.c.moderated

This is essentially what I did and it is similar to the solution you
provided. It seems very elegant and easy to use. The ironic thing is
he posted that code to help him solve another problem. So his problem
was my solution.

Thank you again.
 
Reply With Quote
 
John Harrison
Guest
Posts: n/a
 
      09-12-2004

"JR" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) om...
> (E-Mail Removed) (Jon Bell) wrote in message
> news:<chvsup$hql$(E-Mail Removed)>...
> <snip>>
>
> First, let's just do the error checking for a single input, and not
> worry
>> about the "-1 to quit" yet:
>>
>> int i;
>> cout << "Please enter an integer, and press ENTER: ";
>> while (! (cin >> i))
>> {
>> cin.clear(); // reset stream status flags
>> cin.ignore(1000,'\n'); // skip past next newline (ENTER), or
>> 1000
>> // chars, whichever comes first
>> cout << "Hey dummy, I said enter an integer! Try again: ";
>> }
>>
>> If you want to input repeatedly until the user enters -1, wrap this in
>> another loop that tests for end of data:
>>
>> int i = 0;
>> while (i != -1)
>> {
>> cout << "Please enter an integer, and press ENTER: ";
>> while (! (cin >> i))
>> {
>> cin.clear();
>> cin.ignore(1000,'\n');
>> cout << "Hey dummy, I said enter an integer! Try again: ";
>> }
>> if (i != -1)
>> {
>> // process i normally
>> }
>> }
>>
>> Or you can make the real processing-code a bit cleaner by writing a
>> function to do the input and error-checking:
>>
>> bool GetNumber (int& num)
>> {
>> cout << "Please enter an integer, and press ENTER: ";
>> while (! (cin >> num))
>> {
>> cin.clear();
>> cin.ignore(1000,'\n');
>> cout << "Hey dummy, I said enter an integer! Try again: ";
>> }
>> return (num != -1); // returns true if not at end of input yet
>> }
>>
>> // the real processing-code
>>
>> int i;
>> while (GetNumber(i))
>> {
>> // process i normally
>> }

>
> Thanks All,
>
> Jon I really like your solution. I came across is a couple hours
> after I posted in this post .
>


It has a weakness. Most people would consider 123abc to be erroneous input.
But the code above will read this as the integer 123, then loop and read abc
(which obviously it would consider an error).

If you want to avoid this problem, then you must read as a string and then
convert to an integer.

john



 
Reply With Quote
 
Friedrich Neurauter
Guest
Posts: n/a
 
      09-12-2004

"JR" <(E-Mail Removed)> schrieb im Newsbeitrag
news:(E-Mail Removed) om...
> Hey all,
>
> I have read part seven of the FAQ and searched for an answer but can
> not seem to find one.
>
> I am trying to do the all too common verify the data type with CIN.
> The code from the FAQ looks like this:
>
> #include <iostream>
>
> int main()
> {
> std::cout << "Enter a number, or -1 to quit: ";
> int i = 0;
> while (std::cin >> i) { // GOOD FORM
> if (i == -1) break;
> std::cout << "You entered " << i << '\n';
> }
> }
>
>
> This works well except that I do not want to exit the loop unless a
> valid input is entered. So if I enter an 'a' I want to stay in the
> loop to allow for another chance at input not exit the loop. Can
> someone please provide a modified version of this code that will allow
> this?
>
>
> Thanks,
>
> James


I would do it like this:

#include <iostream>

using namespace std;

//clears an error in an input stream object like cin
//and makes it usable again by clearing the associated stream buffer
int ClearError(istream& isIn) // Clears istream object
{
streambuf* sbpThis;
char szTempBuf[20];
int nCount, nRet = isIn.rdstate();

if (nRet) // Any errors?
{
isIn.clear(); // Clear error flags
sbpThis = isIn.rdbuf(); // Get streambuf pointer
nCount = sbpThis->in_avail(); // Number of characters in buffer

while (nCount) // Extract them to szTempBuf
{
if (nCount > 20)
{
sbpThis->sgetn(szTempBuf, 20);
nCount -= 20;
}
else
{
sbpThis->sgetn(szTempBuf, nCount);
nCount = 0;
}
}
}

return nRet;
}


int main()
{
int pri = 0;
cout << "Enter a number: " << endl;
do
{
ClearError(cin);
cin >> pri;
} while (!cin);
return 0;
}


 
Reply With Quote
 
JR
Guest
Posts: n/a
 
      09-13-2004
"John Harrison" <(E-Mail Removed)> wrote in message news:<(E-Mail Removed)>...
> "JR" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed) om...
> > (E-Mail Removed) (Jon Bell) wrote in message
> > news:<chvsup$hql$(E-Mail Removed)>...
> > <snip>>
> >
> > First, let's just do the error checking for a single input, and not
> > worry
> >> about the "-1 to quit" yet:
> >>
> >> int i;
> >> cout << "Please enter an integer, and press ENTER: ";
> >> while (! (cin >> i))
> >> {
> >> cin.clear(); // reset stream status flags
> >> cin.ignore(1000,'\n'); // skip past next newline (ENTER), or
> >> 1000
> >> // chars, whichever comes first
> >> cout << "Hey dummy, I said enter an integer! Try again: ";
> >> }
> >>
> >> If you want to input repeatedly until the user enters -1, wrap this in
> >> another loop that tests for end of data:
> >>
> >> int i = 0;
> >> while (i != -1)
> >> {
> >> cout << "Please enter an integer, and press ENTER: ";
> >> while (! (cin >> i))
> >> {
> >> cin.clear();
> >> cin.ignore(1000,'\n');
> >> cout << "Hey dummy, I said enter an integer! Try again: ";
> >> }
> >> if (i != -1)
> >> {
> >> // process i normally
> >> }
> >> }
> >>
> >> Or you can make the real processing-code a bit cleaner by writing a
> >> function to do the input and error-checking:
> >>
> >> bool GetNumber (int& num)
> >> {
> >> cout << "Please enter an integer, and press ENTER: ";
> >> while (! (cin >> num))
> >> {
> >> cin.clear();
> >> cin.ignore(1000,'\n');
> >> cout << "Hey dummy, I said enter an integer! Try again: ";
> >> }
> >> return (num != -1); // returns true if not at end of input yet
> >> }
> >>
> >> // the real processing-code
> >>
> >> int i;
> >> while (GetNumber(i))
> >> {
> >> // process i normally
> >> }

> >
> > Thanks All,
> >
> > Jon I really like your solution. I came across is a couple hours
> > after I posted in this post .
> >

>
> It has a weakness. Most people would consider 123abc to be erroneous input.
> But the code above will read this as the integer 123, then loop and read abc
> (which obviously it would consider an error).
>
> If you want to avoid this problem, then you must read as a string and then
> convert to an integer.
>
> john



That is a good point. It also has the weakness of if 100,000 is
entered then only 100 is taken. It does seem that overall the input
as a string makes the most sense.

James
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Triple nested loop python (While loop insde of for loop inside ofwhile loop) Isaac Won Python 9 03-04-2013 10:08 AM
How do I tell "imconplete input" from "valid input"? たか Python 2 05-29-2008 10:32 AM
verifying a date is valid based on integer values for year, month and day of month lbrtchx@hotmail.com Java 1 12-22-2006 08:24 PM
checking and verifying input line in a C program Hulo C Programming 7 02-13-2006 03:07 AM
verifying valid Pointer andreas C++ 16 01-26-2005 11:35 AM



Advertisments