I'm trying to set a basic program that asks for Age, And if the Number entered by the user is less than 99, It will say "Perfect". If the number is MORE than 99, it will say "You Can't be that old, Try again". Additionally, if the user enters something that is not a number (like a letter "m, r" or anything else like "icehfjc") then it will say "That is not a number."
This is my code so far:
#include <iostream>
#include <string>
using namespace std;
int main()
{
int age;
backtoage:
cout << "How old are you?\n";
cin >> age;
if (age < 99)
{
cout << "Perfect!\n";
system("pause");
}
if (age > 99)
{
cout << "You can't be that old, Try again.\n";
system("pause");
system("cls");
goto backtoage;
}
Else
{
cout << "That is not a number, Please Enter a Valid Number\n";
system("pause");
system("cls");
goto backtoage;
}
}
I know "Else" doesn't work because C++ treats letters as integers as well, so
if I write "m" it will take it as a >99 number (because of the integer value of "m") therefore displaying the "you can't be that old" message. but how can I fix this so the program displays "Please enter a number" when a letter is entered? (If anyone could fix the code and write it in a way that works, I'd
be forever grateful).
Any suggestions, tips or hints are very welcome.
so if I write "m" it will take it as a >99 number (because of the integer value of "m")
No, "m" can't be inputted into an int, cin will fail here. So what you should do is to check the status of cin, such as
if (cin >> age) {
// ok
if (age < 99)
{
...
} else
{
...
}
}
else
{
// failed
cout << "That is not a number, Please Enter a Valid Number\n";
system("pause");
system("cls");
cin.clear(); // unset failbit
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // skip bad input
goto backtoage;
}
Check the behavior of std::basic_istream::operator>>
If extraction fails (e.g. if a letter was entered where a digit is expected), value is left unmodified and failbit is set.
BTW: goto is almost obsolete in modern c++ programming. It should be easy to implement the same logic with a loop.
LIVE
You can Try it.It will validate numeric input in C++.Here cin.good() function is return true if the input is valid, if it is not valid it will return fase. cin.ignore() is used to ignore the rest of the
input buffer, which contains the erroneous input and cin.clear() is
used to clear the flag.
#include <iostream>
#include<string>
#include <limits>
using namespace std;
int main() {
backtoage:
int age = 0;
cout << "How old are you?\n";
cin >> age;
if(cin.good()){
if (age < 99){
cout << "Perfect!\n";
system("pause");
}
else if (age > 99){
cout << "You can't be that old, Try again.\n";
system("pause");
system("cls");
goto backtoage;
}
}
else{
cout << "That is not a number, Please Enter a Valid Number\n";
system("pause");
system("cls");
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
goto backtoage;
}
return 0;
}
Input/Output:
How old are you?
k
That is not a number, Please Enter a Valid Number
How old are you?
120
You can't be that old, Try again.
How old are you?
10
Perfect!
first of all , if the users can enter characters like 'm' 'k' or anything else , I suggest using string , then if you want to change to number just substract '0' , so you can work with numbers, secondly programmers , usually do not use goto statement because it can be dangerous and make underfiend behaivor appear into your program.
Sorry for my bad english.
#include<iostream>
#include <string>
using namespace std;
int main()
{
string input;
getline(cin, input);
unsigned int lenght = input.size(),age=0;
for (int i = 0; i < lenght; ++i) {
if (input[i] >= '0' && input[i] <= '9') {
age = age*10+(int)input[i]-'0';
}
}
if (age > 99)
cout << "Nice try , you can`t be that old\n";
else
cout << "perfect!\n";
return 0;
}
Related
Need help figuring out how to cover myself in case the user enters anything other than a number.
I've tried ending my if/elseif statements with an else to cover if the number is ! <,>,or = to. Doesn't seem to work and I kinda see why logically but can't figure out an alternative.
#include <iostream>
#include <ctime>
#include <stdlib.h>
using namespace std;
int main()
{
int number, guess;
srand(time(NULL));
number = rand()%100+1;
do
{
cout << "Guess a number from 1-100.\n";
cin >> guess;
if (guess < number)
cout << "Too low. Try again.\n";
else if(guess > number)
cout << "Too High. Try again.\n";
else if (guess == number)
cout << "Nice job. You got it right on.\n";
else
cout << "Ummm...A number please. Let's try again.\n";
}while (guess != number);
return 0;
}
Read the user input in as a string rather than a number. Then check that the string contains a valid numeric value and then convert to a number:
#include <string>
std::string GuessText;
unsigned long GuessNumber;
size_t NumberStart;
cin >> GuessText;
// check that user entered a valid number
NumberStart = GuessText.find_first_of("0123456789");
if (NumberStart == string::npos)
cout << "Ummm...A number please. Let's try again.\n";
else
{
// get the substring that contains the number
GuessText = GuessText.substr(PositionStart);
// convert string to number
GuessNumber = std::stoul(GuessText, nullptr, 0);
....
}
Try using isnan to check if the input value is a number. It not, have a while loop to keep re-asking for input untill the user inputs a number.
https://en.cppreference.com/w/cpp/numeric/math/isnan
When I run my code, it only prints the decimal parts of the double. On another page, I took a inputted double and printed out the double the way it was inputted.
But for my following code, it only prints out the decimals. For example, when I input 1.95 it only prints out 0.95. Why is it removing the first digit? I see nothing in my code that points to this.
I have already tried it in a more simple way and it worked. And I dont see any problems that would mess with the double in my code.
#include <iostream>
using namespace std;
int main()
{
double price;
char user_input;
do
{
cout << "Enter the purchase price (xx.xx) or `q' to quit: ";
cin >> user_input;
if (user_input == 'q')
{
return 0;
}
else
{
cin >> price;
int multiple = price * 100;
if (multiple % 5 == 0)
{
break;
}
else
{
cout << "Illegal price: Must be a non-negative multiple of 5 cents.\n" << endl;
}
}
} while (user_input != 'q');
cout << price << endl;
}
When I input 1.95, I get 0.95. But the output should be 1.95.
Problem covered in other answer: Reading for the 'q' removed the first character from the stream before it could be parsed into a double.
A solution: Read the double first. If the read fails, check to see if the input is a 'q'.
#include <iostream>
#include <limits>
using namespace std;
int main()
{
double price;
while (true)
{
cout << "Enter the purchase price (xx.xx) or `q' to quit: ";
if (cin >> price)
{
// use price
}
else // reading price failed. Find out why.
{
if (!cin.eof()) // didn't hit the end of the stream
{
// clear fail flag
cin.clear();
char user_input;
if (cin >> user_input && user_input == 'q') // test for q
{
break; // note: Not return. Cannot print price if the
// program returns
}
// Not a q or not readable. clean up whatever crap is still
// in the stream
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
else
{
// someone closed the stream. Not much you can do here but exit
cerr << "Stream closed or broken. Cannot continue.";
return -1;
}
}
}
cout << price << endl;// Undefined behaviour if price was never set.
}
Another reasonable alternative is to read all input as std::string. If the string is not "q", attempt to convert it to a double with std::stod or an std::istringstream.
When you type 1.95 in the command line, variable user_input gets assigned '1', and price gets assigned .95.
I've been learning C++, and this chunk of code is from a simple grading program. But when I try to get the user input, there's a problem.
If I enter a number, whether it be less than 0 or more than 100, or anything in between, my loop works fine.
But if I type in any letter, or any non-alphanumeric character (ex: +, (, %, etc.) I get an infinite loop with "Please enter a grade value between 0 and 100" printed forever.
What am I doing wrong?
Thanks.
int _tmain(int argc, _TCHAR* argv[])
{
using namespace std;
int grade = -1; // grade will hold grade value; initialized to -1
do {
cout << "Please enter a grade value between 0 and 100." << "\n";
cin >> grade;
} while (grade < 0 || grade > 100);
cout << grade << "\n";
printGrade(grade);
return 0;
}
if cin>>grade fails (aka can't parse as int) it does not consume the stream. You can try:
int main()
{ using namespace std;
int grade = -1; // grade will hold grade value; initialized to -1
do {
cout << "Please enter a grade value between 0 and 100." << "\n";
if (!(cin >> grade))
{
cin.clear();
}
} while (grade < 0 || grade > 100);
cout << grade << "\n";
return 0;
}
But this is only part of the problem. Really, you should use std::getline and parse the grade as a full line for correct input.
If cin does not receive valid input for the data type (int), the variable grade is not changed and remains at -1. You can test whether the input was successful like so
bool success = (cin >> grade);
if (! success)
{
cin.clear();
cout << "bad input\n";
break;
}
You can also use this as a shortcut if (! (cin >> grade))
Note that you need to clear the error state of cin before you use it again.
I'm pretty sure the cin failed so you may need to reset its fail flag or something like that.
Add this to your loop:
if (cin.fail())
{
cout << "failed";
cin.clear();
}
Correctly and safely reading until you get valid input is far trickier than you'd think. If there's invalid input, like a letter, the stream is set in a "failure" state, and refuses to read any more characters until you clear the state. But even if you clear the state, that input is still waiting there, in the way. So you have to ignore those characters. The easiest thing to do is simply ignore everything until the next enter key, and then try the input again.
But it gets even more complicated, because if the stream has an error, it gets set in a "bad" state, or if it reaches the end of the stream, it gets set in a "eof" state. Neither of these two are recoverable, so you must detect them and quit the program to avoid an infinite loop. Even more irritating, istreams have a .fail() function, but that checks if it's in fail or bad, which makes it nearly useless in my opinion. So I wrote a little invalid_input which checks if the stream can continue.
Note that get_grade sets the fail flag manually if the input is out-of-range.
#include <iostream>
#include <stdlib.h>
#include <limits>
bool invalid_input(std::istream& in)
{return in.rdstate() == std::ios::failbit;}
std::istream& get_single_grade(std::istream& in, int& grade) {
std::cout << "Please enter a grade value between 0 and 100." << "\n";
if (in>>grade && (grade<0 || grade>100))
in.setstate(std::ios::failbit);
return in;
}
bool get_grade(std::istream& in, int &grade) {
while(invalid_input(get_single_grade(in, grade))) { //while we failed to get data
in.clear(); //clear the failure flag
//ignore the line that the user entered, try to read the next line instead
in.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
}
return in.good();
}
int main(int argc, char* argv[]) {
int grade = -1; // grade will hold grade value; initialized to -1
if (get_grade(std::cin, grade) == false) {
std::cerr << "unxpected EOF or stream error!\n";
return false;
}
std::cout << grade << "\n";
return EXIT_SUCCESS;
}
As you can see here, this doesn't get into an infinite loop when given out of bounds numbers, end of file, a stream failure, or invalid characters.
I just started with c++ (coming from java) and I'm trying to do some basic exercises. The idea is to ask for any input other than 5, if the user inputs 5, display a message, and if the user inputs anything other than 5 ten times, display another message. Here's the code:
void notFive () {
int count = 0;
while (count < 10) {
int input = 0;
cout << "Enter any number other than 5." << endl;
cin >> input;
if (input == 5)
break;
count++;
}
if (count == 10)
cout<<"You are more patient than I am, you win.";
else
cout << "You weren't supposed to enter 5!";
}
}
My problem is that all this code does is print out "Enter any number other than 5." 10 times, then say "You are more patient that I am, you win." any ideas what is wrong?
if you guys want all my code (to make sure I'm not just being an idiot) here it is:
#include <iostream>
#include <stdio.h>
using namespace std;
class Hello {
public:
void notFive () {
int count = 0;
while (count < 10) {
int input = 0;
cout << "Enter any number other than 5." << endl;
if ( ! (cin >> input) ) {
cout << "std::cin is in a bad state! Aborting!" << endl;
return;
}
if (input == 5)
break;
count++;
}
if (count == 10)
cout<<"You are more patient than I am, you win.";
else
cout << "You weren't supposed to enter 5!";
}
}hello;
int main() {
Hello h;
h.notFive();
return 0;
}
Your code works perfectly for me (in Visual Studio 2012) when I change notFive to main. Your problem must lie outside this code (possibly because cin is in a broken state, as others have suggested).
Change this line:
cin >> input
To this:
if ( ! (cin >> input) ) {
cout << "std::cin is in a bad state! Aborting!" << endl;
return;
}
The behavior you describe is what would happen if Something Bad happened to cin before this code was run.
Edit:
Add this same code to earlier uses of cin to find out where it's entering a bad state.
An example of this happening would be if the code tried to read an int, and the user typed a letter of the alphabet.
You can also call cin.clear(); to restore the working state of cin.
Here are my comments:
fflush(stdin) is not valid. The stdin cannot be flushed. Also,
this may not be the same input as cin.
You need to check for cin.fail after cin >> input. If I enter a
letter, your input statement will fail.
So I am making this Guess the number game in c++ that looks like this:
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main()
{
srand(time(0));
int secretNumber = rand() % 100 + 1; //Generate "Random number"
int nbrOfGuesses = 0;
int userInput;
cout<<"\t************************************"<<endl;
cout<<"\t* *"<<endl;
cout<<"\t* Guess the number! *"<<endl;
cout<<"\t* *"<<endl;
cout<<"\t************************************"<<endl;
cout<<endl;
cout << "Try to find the secret int number: " << endl;
//While input is good
while(cin.good())
{
//Do this
do {
cin>>userInput;
nbrOfGuesses++;
if (userInput>secretNumber)
cout << "Smaller!\n";
else if(userInput<secretNumber)
cout << "Bigger!\n"; // <-- Infinite loop here when you enter something other than an integer
else //Also using this as a backup of (cin.good())
cout << "Something went wrong with the read";
break;
} while(userInput!=secretNumber);
cout << "\nCongratulations! You got it in " << nbrOfGuesses << " guesses\n";
}
system("pause");
return 0;
}
*Sorry if the code is note very elegant
As you can see, the code works great until you enter a random caracter like '&' or 'j' or anything else that isn't an integer...Then it loops at cout<<"Bigger!";
So my question is: What is causing this?
Check this post, it is about the same problem. To summarize:
cin>>userInput;
if (cin.fail()) {
cout<<"Invalid Entry, please try again."<<endl;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
Thanks ildjarn for pointing the missing ignore statement, I missed that part even though its clearly mentioned in the post I linked to!!
See this FAQ: How can I get std::cin to skip invalid input characters?
cin>>userInput;
If it cannot read an integet, the bad bit is set for the cin stream.
You should check and clear afterwords.
if ( cin.fail() )
{
cin.clear();
try again
}