I am just a newbie to programming and I was trying to write a while loop that runs as long as the input (num) is not a integer which doesn't ends with zero. What happen is when I enter a number that ends with zero, the program runs the loop correctly, but when i enter something nonsense such as rofl the program only print The input is not valid. and won't repeat the loop. I have tried to look for solutions but I am still stuck after a hour. Anyone can help me here? Thx so much!
void rev_sum() {
int num;
int a = 1;
while (a < 2) {
cout << "Please input a natural number without zero at the end:\n";
cin >> num;
if (!cin) {
cout << "The input is not valid.\n";
cin.clear();
cin.ignore(INT_MAX);
}
if (num % 10 == 0) {
cout << "The number cannot have zero at the end\n";
} else {
cout << "gj\n";
break;
}
}
}
Try replacing
cin.ignore(INT_MAX);
With
cin.ignore(numeric_limits<streamsize>::max(), '\n');
And change the
if (num % 10 == 0)
To
else if (num % 10 == 0)
Your final code should look like this:
void rev_sum() {
int num;
int a = 1;
while (a < 2) {
cout << "Please input a natural number without zero at the end:\n";
cin >> num;
if (!cin) {
cout << "The input is not valid.\n";
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
else if (num % 10 == 0) {
cout << "The number cannot have zero at the end\n";
} else {
cout << "gj\n";
break;
}
}
}
if (num % 10 == 0) {
could be
else if (num % 10 == 0) {
otherwise the other else case might get executed
You set a = 1 at the start of the loop and then never change a which means the only way to leave your while loop is if you hit the break statement. If your loop is not looping then it must be stuck somewhere. I'm unfamiliar with the statements if (!cin) and cin.ignore(...) so those are top suspects to check (or change). The statement cin >> num; completes no matter what they type so you can check to see what 'num' is equal to when you enter "rofl". Then after it fails, you still use num so you are processing this unintentional entry. You can add continue; after cin.ignore(...) to jump back to the top of the while loop and ask the question again. You can also print something after the while loop in order to know when you get out.
With all that said, I would never trust the user to enter acceptable information and I would never trust cin to process it for me. Personally, I would read cin as a string using cin.getline(buffer, buffer_size); And then I would complain to the user if they filled the buffer or gave me something that was not an integer (which you can check with a function like scanf()). Then you can spit back exactly what they gave you and you can be specific about your complaint.
Would it not make more sense to only check that the number ends in 0 if the input was valid....
void rev_sum() {
int num;
int a = 1;
while (a < 2) {
cout << "Please input a natural number without zero at the end:\n";
cin >> num;
if (!cin) {
cout << "The input is not valid.\n";
cin.clear();
cin.ignore(INT_MAX);
} else {
if (num % 10 == 0) {
cout << "The number cannot have zero at the end\n";
} else {
cout << "gj\n";
break;
}
}
}
}
cin.ignore(numeric_limits<streamsize>::max())
Related
This question already has answers here:
Checking cin input stream produces an integer
(8 answers)
Closed 4 years ago.
I want to obtain an input from the user and validate it as an integer, however my method seems to fail, when a letter or word the program just ends. Any one have a quick and easy fix for this?
int getUserInput(){
int maxNumber;
// the user input a valid integer, process it
if (cin >> maxNumber)
{
if (maxNumber>1 || maxNumber<=100) {
return maxNumber;
}
} else{
getUserInput();
}
}
If the user does not type in an integer, your code enters an infinite recursive loop that it does not recover from, eventually overflowing the call stack.
Try something more like this instead:
int getUserInput()
{
int number;
cout << "Enter a number between 1 - 100: ";
do
{
// if the user input a valid integer, process it
if (cin >> number)
{
if (number >= 1 && number <= 100)
break;
cout << "Number out of range, try again: ";
}
else
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Invalid input, try again: ";
}
}
while (true);
return number;
}
You didn't state what range you wanted the input to be in so adjust accordingly.
int getUserInput() {
int maxNumber;
while (!(cin >> maxNumber) || maxNumber <= 1 || 100 < maxNumber) {
if (cin)
cout << "number out of range, try again: ";
else {
cin.clear();
cin.ignore(numeric_limits<int>::max(), '\n');
cout << "Not a number, please try again : ";
}
}
return maxNumber;
}
I am creating a simple code to take integer value 10 times. If at any point, the users enters the value '5', the system should print a message, "You entered 5, you lose". Here is the code
int main()
{
int num = 0;
int i;
for (i = 1; i<= 10; i++)
{
cout << "Enter a number other than 5\n";
cin >> num;
if (num == 5)
{
cout << "Hey, you entered 5. You lose!\n";
break;
}
}
cout << "You win!";
return 0;
}
Now what I dont know is, how do close the program after users enters 5. I am very new to coding so Im really sorry if this question sound stupid. Also, it would be vet nice of you if you could explain in the most easiest way you can. Thank you
You could do this:
for (i = 1; i<= 10; i++)
{
cout << "Enter a number other than 5\n";
cin >> num;
if (num == 5)
{
cout << "Hey, you entered 5. You lose!\n";
return 0; // This will end function main and return 0. Thus your program will end.
}
}
And some more reading.
The way you had it break would simply stop the for loop. This however:
cout << "You win!";
would still get printed. If you use return, no more statements from main will get executed. Because return will end the function in which it is called, in this case, main.
Now what I dont know is, how do close the program after users enters 5.
Replace
break;
with
exit(0);
or
return 0;
break will only exit from the loop, and you're printing cout << "You win!"; unconditionally.
The other two approaches mentioned above are undoubtedly the best. But still, if you have some unfinished business that you want to take care of even after the user enters 5 you can take help of a temporary variable say temp.
int main()
{
int num = 0,tmp=0;
int i;
for (i = 1; i<= 10; i++) {
cout << "Enter a number other than 5\n";
cin >> num;
if (num == 5) {
tmp=1;
cout << "Hey, you entered 5. You lose!\n";
break;
}
//unfinished work
}
//unfinished work
if(tmp==0)
cout << "You win!";
return 0;
}
I need to do a Guessing game where the program generates a random number and the user has to guess the number. If the user guesses the number in less than 10 guesses the program congratulates them and lets them know they were under 10 guesses. If they were above 10 guesses then it lets them know it was above 10, etc.
The problem I'm facing is if, for example, the user guesses the number in 3 tries and then decides to play again with a whole new other number, and this time guesses it in 8 tries, instead of still congratulating them because it was under 10 tries, it counts the 3 tries from the previous game. This then leads the program to tell them they were over 10 tries, even though they were not. I don't know how to fix this. The code I've done so far is as follows:
int main()
{
srand(time(0));
int guess;
int number;
char selection = 'y';
int numberOfGuesses=0;
while(selection == 'y' || selection == 'Y')
{
number = rand() % 1000 + 1;
cout << "I have a number between 1 and 1000.\nCan you guess my number?\nPlease type your first guess: ";
cin >>guess;
do
{
if(number > guess)
{
cout << "Too low. Try again: " << endl;
cin >> guess;
numberOfGuesses++;
}
if (number < guess)
{
cout << "Too high. Try again: " << endl;
cin >> guess;
numberOfGuesses++;
}
}
while(number != guess);
if(numberOfGuesses < 9)
{
cout << "You guessed the number in less than 10 guesses!\n Would you like to play again (y or n)?";
cin >> selection;
}
else if(numberOfGuesses > 9)
{
cout << "You guessed the number\n Would you like to play again (y or n)?";
cin >> selection;
}
else if(numberOfGuesses == 9)
{
cout << "You guessed the number.\n Would you like to play again (y or n)?";
cin >> selection;
}
}
return 0;
}
The problem is that you are not resetting the counter.
Just put int numberOfGuesses=0; within the while loop:
while(selection == 'y' || selection == 'Y')
{
int numberOfGuesses=0;
....
}
You need to set numberOfGuesses to 0 before every game. Your program only sets it once when the program first launched.
You are not resetting numberOfGuesses to zero after each round. You can solve the problem using one of couple of methods.
Reset the value of numberOfGuesses to zero at the end of the first while loop.
while(selection == 'y' || selection == 'Y')
{
...
numberOfGuesses = 0;
}
Don't define the variable until the start of that while loop. Define it as the first statement and initialize it zero.
while(selection == 'y' || selection == 'Y')
{
int numberOfGuesses = 0;
...
}
I have a simple recursive factorial program. The main point of this exercise is to handle exceptions. We've been imposed with the limitations of having no negative numbers and no number larger than 12.
{
int factorial(int);
int number = 0;
string s;
while(number != -1)
{
cout << "Please enter a number 1 - 12 " <<endl;
cout << "or -1 to quit the program: ";
try{
cin >> number;
if (number < 0 || number > 12)
throw number;
else
cout << number << " factorial is: " << factorial(number)<<"\n" << endl;
}catch(int number)
{
cout<< "Your number violates the rules; " <<number<<" is either negative or greater than 12.\n"<<endl;
}
}
}
int factorial(int number) {
int temp;
if(number <=1)
return 1;
temp = number * factorial(number - 1);
return temp;
}
My error handling seems like it's working fine, and it's a new concept to me. However, I'd like to do a better job of handling errors. For example, when I type in anything that's not a number, like say a "p" the program starts an infinite loop. How could I code to check and make sure that it's indeed a number a user is putting in?
Thank you.
Add another condition to test the input. For example you can do this.
...
try{
cin >> number;
if (!cin) {
//error msg here
break;
} else if (number < 0 || number > 12)
...
I'm basically expecting a number as input. The magnitude is negligible now as I know my else if loop works fine. But testing if its a number proves to be a bit trickier. I just want to call the function again and start over if the user enters in something alphanumeric or just plain words. Or pressed enter. Something that is not a number. I tried !cin since I am inputting into int numTemp, but that just results in an infinite loop that spills out "what is the bitrate" countless times. Anyone know what I'm doing wrong? I tried putting cin.clear() and cin.ignore(100, "\n") inside the first if statement but to no avail. Thanks in advance.
bool iTunes::setBitRate()
{
cout << "What is the bitrate? ";
int numTemp;
cin >> numTemp;
if (!cin)
{
cout << "WRONG" << endl;
setBitRate();
}
else if( numTemp < MIN_BITRATE || numTemp > MAX_BITRATE)
{
cout << "Bit Rate out of range" << endl;
setBitRate();
}
else
{
bitRate = numTemp;
}
}
You can just read a string from the user instead of an int, and then check it and prompt for new input if you don't like the string (e.g. if it doesn't cleanly convert to a number, which you can check with strtol).
If you want to check whether the input is a number or character, you can use isdigit, but you have to pass it a char and then when it is a digit you can convert it to a int with atoi.
When the statement cin >> numTemp fails due to non-numeric input the character causing the failure is NOT removed from the input stream. So the next time the stream extraction operator is called it will see the same non-numeric input as the last time. To avoid this you need to skip the existing input.
One way of doing this is to use getline() to read a complete line of text before trying to converting it to and integer. The folllowing code snippet illustrates this:
#include <cstdlib>
bool getint(istream& in, int & out) {
string line;
getline(in, line);
char* endptr;
out = strtol(line.c_str(), &endptr, 10);
return endptr!=line.c_str();
}
bool iTunes::setBitRate()
{
cout << "What is the bitrate? ";
int numTemp;
if ( !getint(cin, numTemp) && cin )
{
cout << "WRONG" << endl;
setBitRate();
}
else if( numTemp < MIN_BITRATE || numTemp > MAX_BITRATE)
{
cout << "Bit Rate out of range" << endl;
setBitRate();
}
else
{
bitRate = numTemp;
}
}
NOTE: You should also check the status of cin after each read to ensure that some error has not occurred.
i think this will helps
bool iTunes::setBitRate()
{
cout << "What is the bitrate? ";
int numTemp = 0;
cin >> numTemp;
if (!numTemp)
{
cout << "WRONG" << endl;
setBitRate();
}
else if( numTemp < MIN_BITRATE || numTemp > MAX_BITRATE)
{
cout << "Bit Rate out of range" << endl;
setBitRate();
}
else
{
bitRate = numTemp;
}
}