Hello guys~
I am new in this forum, but I've been studying (by my self) C++ for 4 months.
The question is:
In the code below I am running a very simple program that outpt 'spelled-out' numbers when you input any integer between 1 and 10.
It works fine.
Now! How can I instruct the program to act sensibly with bad inputs?
I can say "if the number is negative then bla bla.." but how about a string??
If you input "a" in this simple code, the program crashes. I'd rather like it to come up wih somthing like "error, please input a number"
How can perform that "check"?
If the program is waiting for a string, the check will never fail,because even "3" can be read as a string.
Please, could somebody help me? (no complicated answers, I am a bit stupid, only simple but good ideas. I might not even need any code, I'd appreciate so much any quick explanation on what to do in these situations)
while (cin>>nmb)
{
if (nmb>(-1) and nmb<10)
{for (int i=0;i<nmbs.size();i++)
if (nmb==i) cout<<"\n"<<nmbs[i]<<"\n\n";}
else cout<<"\nsorry, what the f**k was that?\n\n";
}
Also, 'same question' (but with a practical example)
Assuming I wanted to make a video-game one day, how can I make a loop "serching" accross the whole program for a particular string (a password, an exit) while I am prompting the user to input numbers?
while we ask for ints (for example) how can we also check that any string (in case of bad-input-protection) or one particular string (in case of a 'password' as an exit) is not being entered?
How can you allow players to exit at ANY point in time?
This is exactly what I have been trying to ask above! I noticed the C++ "feels" ONLY the "closest" loop, the last one, not the first one, the out-most loop..
Have I given you an idea of what I mean?
(the code below is an even sillier example, the "no-check" is ignored)
int nmb=0;
string exit="";
if (exit!="no")
while (int!="wow") {cin>>exit; cout<<"woah!!!";}
Well, I would suggest you this: Always scan for strings using getline, then convert the numbers into ints for a function, for example, saying something like "Invalid input" if it has other characters. I don't know many details about this, sorry.
Thank you for your attempt at helping me! I appreciate that.
Do you mean:
I should prompt the user to input a STRING first, then check whether the string happens to be "one" "two "three" etc.. and turn ONLY those into numbers?
:)
Yes!
That is a good idea. thanks.
It solves my problem in this context.
But how about another context? where an infinte number of "fine" inputs is possible?
To avoid using the cctype library you could use a member function of the istream class ( cin is an object of class istream ) In case you are unaware cin(as in the thing you do cin >> input with) is actually an object of type istream (just like int x; where x is an object of type int.)
The way you would use it is you would get the input and then check if (cin.bad()) //some code here
If you want to see an example a similar question was asked and a solution was provided (again it may be to heavy for the moment so don't feel discouraged if it's just looks like abunch of gibberish)
edit: Whoops I only provided an alternative method, AFAIK you shouldn't be doing it any other way, but I suppose you could iterate through all your valid inputs ( as in 0 - 9 ) and if the user input doesn't match any one of them you could just re-prompt for valid input. This is an inefficient way to do this however.
Thank you so much.
Yea, I understand. It's my biggest limit.
I've just started and I want my little silly programs to be "bullet-proof".
I am having a look at that, and I will keep studying in the mean time :)
How can you allow players to exit at ANY point in time?
No magic function to quit at any time, you would have to code it in for every time you accept user input. The simplest way here is to include <cstdlib> and use the exit function: http://www.cplusplus.com/reference/clibrary/cstdlib/exit/
I've just started and I want my little silly programs to be "bullet-proof".
while (cin >> nmb) is pretty close. Basically, the >> operator returns the cin object itself, so you're looping while >> works. The trick is to loop for the opposite (while it doesn't work), while (!(cin >> nmb)).
1 2 3 4 5 6 7 8 9 10 11 12
double getNum(void)
{
double num;
while (!(cin >> num)) //while the extraction breaks cin
{
cin.clear(); // fix cin
cin.ignore(80, '\n'); // remove what broke it from the buffer
cout << "Numbers only please. Try Again: ";
}
cin.ignore(80, '\n'); // clear the buffer of any remaining characters
return num;
}
Foolproof. It may act funny if you enter more than 80 characters, but will also resolve itself.
To get an integer specifically, think about the difference between a double and an int. An int doesn't have a decimal:
1 2 3 4 5 6 7 8 9 10
int getInt(void)
{
double num = getNum(); // getNum() ensures a numerical input
while (num != static_cast<int>(num))
{
cout << "Integers only please. Try Again: ";
num = getNum();
}
returnstatic_cast<int>(num);
}
Which is then made something more menu friendly:
1 2 3 4 5 6 7 8 9 10
int getIntInRange(int low, int high)
{
int num = getInt(); // Ensures a number and an integer
while (num < low || num > high)
{
cout << "Integer must be from " << low << " to " << high << ". Try Again: ";
num = getInt();
}
return num;
}
Finally, incorporate into your menu:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
int main(void)
{
int choice;
do
{
cout << "1) Play\n"
<< "2) Quit\n";
cout << "Please make a choice: ";
choice = getIntInRange(1, 2);
switch (choice)
{
case 1: cout << "Play is good\n"; break;
case 2: cout << "That was fun\n"; break;
}
}
while (choice < 2);
return 0;
}
Hope that helps a little.
edit: I (and the repliers of that post) don't like the use of exceptions there. I made this up for a more reasonable use:
#include <iostream>
usingnamespace std;
double getNum(void)
{
double num;
if (!(cin >> num))
{
cin.clear(); // fix cin
cin.ignore(80, '\n'); // remove what broke it from the buffer
throw"Numbers only";
}
cin.ignore(80, '\n'); // clear the buffer of any remaining characters
return num;
}
int getInt(void)
{
double num = getNum(); // getNum() ensures a numerical input
if (num != static_cast<int>(num))
{
throw"Integers only.";
}
returnstatic_cast<int>(num);
}
int getIntInRange(int low, int high)
{
int num = getInt(); // Ensures a number and an integer
if (num < low || num > high)
{
throw"Integer out of range";
}
return num;
}
int main(){
int choice;
do
{
cout << "1) Play\n"
<< "2) Quit\n";
cout << "Please make a choice: ";
try
{
choice = getIntInRange(1, 2);
}
catch (constchar* error)
{
cout << error << endl;
choice = 1;
}
switch (choice)
{
case 1: cout << "Play is good\n"; break;
case 2: cout << "That was fun\n"; break;
}
}
while (choice < 2);
return 0;
}
What is to note is that the catch part of the code manages to make the program continue to run in a smooth fashion.
that actually explains a lot thanks, and so far I have had quite a few trouble at understanding how to make the most of separate functions.
Now finally I get to see a little program that makes large use of them.
nice
Only one thing,
(num != static_cast<int>(num))
?? I think I don't get what this means.
Also, when you say:
edit: I (and the repliers of that post) don't like the use of exceptions there. I made this up for a more reasonable use:
I am not sure I get what you mean. I can't spot any dfference between the first code and the edit (apart from