-
problem with input
In the code below I want to only accept input of 1, 2, 3, 4, 5 or 6.
This works in that it will accept only one of those numbers and return it to my main.
If I enter a number such as '22' say, then it reprompts for a correct number; but if I input 'a' it locks the program up.
Is there a better way of asking for my input to stop this happening?
Code:
int menu ()
{
int choice=0;
cout<<endl<<"JayCee's Player Information Storage, Recall, and Amendment Facility"<<endl<<endl<<endl;
cout<<"Please choose from :"<<endl<<endl<<endl;
cout<<" 1 - Ceate a new data file"<<endl<<endl;
cout<<" 2 - Add a record to an existing file"<<endl<<endl;
cout<<" 3 - Delete a record from a file"<<endl<<endl;
cout<<" 4 - Read a single record from a file"<<endl<<endl;
cout<<" 5 - Read whole file into an array"<<endl<<endl;
cout<<" 6 - End the program"<<endl<<endl<<endl;
cout<<" Choice - _\b";
while (choice<1 || choice>6)
{
cin>>choice;
}
return choice;
}
-
try using a simple if else looping. The Final else must say please enter a valid value. switch is also one better way.
-
Welcome to the intricacies of I/O in C/C++. Your input loop is designed to accept integer input only and when it comes across something that does not fit into its expectations, "a" for example, then odd things happen. What is occurring here is that the cin stream goes into an error state where further operations on that stream are ineffective. The bad data that caused the stream to go into its errored state remains in the input stream and will continue to cause problems until it is cleared out.
The way to deal with such an occurrence is to first clear the error state on the stream by calling... you guessed it, the stream's "clear" member function. Next you want to wipe out the bad data in the stream that caused the problem in the first place and you do so by calling the "ignore" member function on the stream.
In practice, your loop might look more like this:
Code:
#include <limits>
...
while (choice<1 || choice>6)
{
cin>>choice;
if( !cin )
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
}
There are other ways of writing that loop but the basics are in place: check if the stream is in an errored/bad state and clear the error and ignore the bad data if it is. The limits header is needed for the numeric_limits part. Most people would also reprompt the user to enter good data.
-
Thanks very much for that suggestion, I have changed it to :
Code:
if ((!cin) || (choice<1 || choice>6))
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout<<" Please enter a valid choice - _\b";
}
and it gives a nice clean prompt if a number outside 1-6 or a character is input.
There is only one thing I would like to change now and that is each new prompt is on a new line and I can't find an escape code to allow me to do it so they appear over the top of each other ie in the same place each time, maybe that isn't really necessary but I thought it would look better. If I am asking something I should be able to look up please do tell me but I have tried a \t and \v but neither seems to do as I want.
-
-
Thanks for that Elysia but unfortunately that appears to do nothing.
-
Well, it's platform dependent, so if it doesn't work, you have to resort to OS-specific APIs.