I'm trying to write a program which calculates prime numbers and I have issues with a do-while-loop I am using.
Code:
#include <iostream>
#include <conio.h>
using namespace std;
int main()
{
unsigned long int lower_limit;
unsigned long int upper_limit;
cout << "\n" << "Program calculates prime numbers in a given range between 2 and 4.294.967.295.";
cout << "\n" << "Input range in which prime numbers are to be calculated... ";
do
{
cout << "\n\n" << "Lower Limit:\t"; cin >> lower_limit;
cout << "\n" << "Upper Limit:\t"; cin >> upper_limit;
if(lower_limit >= upper_limit)
{
cout << "\nInvalid Input: Value of Upper Limit has to be bigger than value of Lower Limit.";
cout << "\nSelect new numbers.";
}
if(!(cin >> lower_limit) || !(cin >> upper_limit))
{
cout << "\nInvalid Input: Values of Lower Limit and Upper Limit have to be integers.";
cout << "\nSelect new numbers.";
}
}while(lower_limit >= upper_limit || !(cin >> lower_limit) || !(cin >> upper_limit));
return(0);
}
If I input values to trigger Lower Limit >= Upper Limit it triggers the first error properly, but doesn't repeat the do-while-loop afterwards and doesn't close the program (return(0)) either... So the program is not repeating the do-while-loop, neither is the program exiting it. I really have no clue what it is actually doing there.
If I input values to trigger !(cin >> lower_limit) || !(cin >> upper_limit) ("adfd" or the like) the whole program just goes mental and rapidly repeats the do-while-loop, even ignoring the cin >> lower_limit; and cin >> upper_limit; statements.
Does anybody have an idea that can help me out?
Cheers!
One point is that if you get invalid input, you need to clear the error state by:
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
Your loop should be changed to something like:
do
{
while ( !(cin >> lower_limit >> upper_limit) ) {
cout << "Invalid input, Please re-enter\n";
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
if(lower_limit >= upper_limit)
{
cout << "\nInvalid Input: Value of Upper Limit has to be bigger than value of Lower Limit.";
cout << "\nSelect new numbers.";
}
} while(lower_limit >= upper_limit);
Related
I currently have a function set up that asks the user for an int, obtains that int, and then checks to make sure that the input meets a certain specification. In this case, its expected that the input will be an integer between -10 and 100. As of now, if I input any string of letters E.G. "gfUIWYDUF", the function returns a 0. Why is this happening and how do I fix it?
int readUserInput() {
cout << "What is the answer?: " << endl;
int answer;
do {
cin >> answer;
if (!cin || answer < -10 || answer > 100) {
cout << "Invalid Input!" << endl;
cout << "What is the answer?: " << endl;
cin.clear();
cin.ignore();
}
} while(!cin || answer < -10 || answer > 100);
return answer;
}
If you play with the input values you will find that cin >> scans from left to right until it finds any non-numeric value. It then evaluates the numbers it did find.
For example, putting:
57gh5
Returns 57
If you enter only numeric characters, you have a score of 0.
If you cin >> string instead, then you will be able to parse/validate the string and convert a valid number into an int
The problem is that your validation loop for this type of input depends on the error state of std::cin. However, you clear that error state before the loop checks for it.
The simplest way to fix this is to move your reading from std::cin to after the clear() like this:
// Read first
cin >> answer;
do {
if (!cin || answer < -10 || answer > 100) {
cout << "Invalid Input!" << endl;
cout << "What is the answer?: " << endl;
cin.clear();
cin.ignore();
cin >> answer;
}
} while(!cin || answer < -10 || answer > 100);
Though, I think I prefer using a regular while loop instead myself:
cin >> answer;
while(!cin || answer < -10 || answer > 100) {
cout << "Invalid Input!" << endl;
cout << "What is the answer?: " << endl;
cin.clear();
cin.ignore();
cin >> answer;
}
This feels cleaner to me, but that's just me. Both loops will work.
0 is returned as the initial value of answer
You may use cin.fail() to check if the input is valid.
int readUserInput() {
cout << "What is the answer?: " << endl;
int answer;
do {
cin >> answer;
if (cin.fail() || !cin || answer < -10 || answer > 100) {
cout << "Invalid Input!" << endl;
cout << "What is the answer?: " << endl;
cin.clear();
cin.ignore();
}
} while(cin.fail() || !cin || answer < -10 || answer > 100);
return answer;
}
I'm trying to make a validation loop in C++ that checks the user's input until they enter a number between 0 and 100 and however my loop only checks the first condition. Any guidance is appreciated!
#include <iostream>
using namespace std;
int main()
{
const int max_num = 100;
const int min_num = 0;
int num;
cout << "Enter a number between 0 and 100" << endl;
cin >> num;
do {
if (!(cin >> num))
{
cout << "ERROR:The value provided was not a number" << endl;
cin.clear();
cin.ignore(1024, '\n');
cout << "Enter a number between 0 and 100" << endl;
cin >> num;
}
else if (num<min_num || num>max_num)
{
cout << "ERROR: value out of range" << endl;
cin.clear();
cin.ignore(1024, '\n');
cout << "Enter a number between 0 and 100" << endl;
cin >> num;
}
} while (!(cin >> num) || (num<min_num || num>max_num));
return 0;
}
Add lots of logging to your code so that you know what it's doing. This will help you find the problem. For example, instead of:
cout << "Enter a number between 0 and 100" << endl;
cin >> num;
Try:
cout << "Enter a number between 0 and 100" << endl;
cerr << "About to read into num outside the loop" << endl;
cin >> num;
cerr << "Read into num outside the loop, got: " << num << endl;
And so on, throughout your code. This should give you enough information to find the bug. Alternatively, use a debugger with a single step function to accomplish the same thing.
Check that in the part of while:
instead of
while (!(cin >> num) || (num<min_num || num>max_num));
this:
while (!cin || (num<min_num || num>max_num));
the same for the upper if
cin >> num means putting user input to the variable num . So you are trying to take user inputs 2 times in the loop. Maybe the check condition: (num == (int)num)will solve your problem. It will try to verify the number you have stored in num is really of the type int
I need help debugging my code. So I made a program that adds and subtracts numbers but when I implemented a do-while loop to replay the program, the actual program closes and does not perform the do-while loop and does not replay the program. Is their something wrong with my code?
P.S. I am also using codeblocks IDE
#include <iostream>
using namespace std;
int main()
{
// Addition and Subtraction Calculator
int a_number, number1, number2, sum, number3, number4, subsum, again;
// subsum = subtracted sum
// number1 and number2 are variables that hold the users input for addition
// number3 and number4 are variables that hold the users input for subtraction
do
{
cout << "Addition & Subtraction Calculator" << endl;
cout << "-------------------------------------------" << endl;
cout << "1. Addition" << endl;
cout << "2. Subtraction" << endl;
cout << "Please enter a number [1 or 2]" << endl;
cin >> a_number;
while (a_number < 1 || a_number > 2)
{
cout << "Please enter either 1 or 2" << endl;
cin >> a_number;
}
switch (a_number)
{
case 1:
cout << "Please enter a number" << endl;
cin >> number1;
cout << "Please enter another number" << endl;
cin >> number2;
sum = (number1 + number2);
cout << "The sum is " << sum << endl;
break;
case 2:
cout << "Please enter a number" << endl;
cin >> number3;
cout << "Please enter another number" << endl;
cin >> number4;
subsum = (number3 - number4);
cout << "The answer to the subtraction problem is: " << subsum << endl;
break;
}
cout << "Do you want to try again? [y/n]" << endl;
cin >> again;
}
while (again == 'y' || again == 'n');
return 0;
}
OK. So the OP is using an int where they should have used a char. That covers the immediate problem. int again should be char again.
But there is an important point the other answers have missed.
int again;
cin >> again;
The user input will be converted into an integer as required by again. Inputting y or n fails to convert to an integer as neither y nor n are numbers and cannot be converted. again remains unchanged, keeping whatever junk value happened to be sitting at that spot in memory and might actually be a y or an n, but more importantly cin is now in an error state that needs to be cleared before continuing.
cin would have notified the OP of this if it had been tested. So let's test it.
int again;
if (cin >> again)
{
// got good input. Do something with it.
}
else
{
// got bad input.
cin.clear();
// that bad input is still in the buffer and needs to be removed
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
// the above line will wipe out everything to the end of the stream or
// end of line, whichever comes first.
}
Why this is important: Because the OP is doing a lot of numeric input with cin and none of it is checked for validity. For example:
cout << "Please enter a number [1 or 2]" << endl;
cin >> a_number;
The program is broken completely and cannot exit without a kill signal if the user types in anything but a number.
Always check the error state and return codes. They are there to help. Always validate user input before using it. Users are evil and will try to break your program. Don't let them.
use char again; instead of int again;
in your code again is int and when in (again == 'y' || again == 'n')you compare again (an int) with a char, that does not make sense
You need to change the again variable to a char datatype because you need to store text. Something like this:
char again;
You also need to change the while statement to:
while(again != "n");
Or
while(again == "y");
I am trying to verify the user input, but I have tried two compilers and I either have one of two things happen. Either it will:
-Constantly loop the error message without asking for user input
OR
-Wait for user input, and if the input is incorrect, will constantly loop the error message.
Here is the code:
cout << "Input number of the equation you want to use (1,2,3): " ;
cin >> userInput;
cout << endl;
while (userInput <= 0 || userInput >= 4)
{
cout << "Please enter a correct input (1,2,3): " ;
cin >> userInput;
cout << endl;
}
if (userInput == 1)
{
userInput is declared as an integer. Is there an easier way to verify user input, or a while loop is necessary? I am still very new to coding.
While using int userInput seems straight forward, it fails when the user inputs non-numeric values. You can use a std::string instead and check, if it contains a numeric value
std::string userInput;
int value;
std::cout << "Input number of the equation you want to use (1,2,3): " ;
while (std::cin >> userInput) {
std::istringstream s(userInput);
s >> value;
if (value >= 1 && value <= 3)
break;
std::cout << "Please enter a correct input (1,2,3): " ;
}
std::istringstream is similar to other input streams. It provides input from an internal memory buffer, in this case the value provided by userInput.
I would add an additional check to make sure that if the user enters non-integral input, the stream is cleared before attempting the next read.
cout << "Input number of the equation you want to use (1,2,3): " ;
cin >> userInput;
cout << endl;
while (userInput <= 0 || userInput >= 4)
{
if ( !cin.good() )
{
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
cout << "Please enter a correct input (1,2,3): " ;
cin >> userInput;
cout << endl;
}
I would suggest using a do loop instead so you have less repeated lines
int userInput = 0;
do
{
cout << "Input number of the equation you want to use (1,2,3): " ;
cin >> userInput;
cout << endl;
if ( !cin.good() )
{
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
} while (userInput <= 0 || userInput >= 4);
You don't want to cin >> int, if you are to perform any error checking. If the user enters a non-integer, you'll end up in difficult-to-recover-from situations.
Rather, cin into a string, perform any error checking you want and convert the string to a integer:
long x;
string sx;
cin >> sx;
x = strtol(sx.c_str(), NULL, 10);
New to C++. Having issues correctly looping while handling errors. I am trying to check if user input is an integer, and is positive.
do{
cout << "Please enter an integer.";
cin >> n;
if (cin.good())
{
if (n < 0) {cout << "Negative.";}
else {cout << "Positive.";}
}
else
{
cout << "Not an integer.";
cin.clear();
cin.ignore();
}
}while (!cin.good() || n < 0);
cout << "\ndone.";
When a non-integer is entered, the loop breaks. I feel like I am misunderstanding the inherent usage of cin.clear() and cin.ignore() and the status of cin during this loop. If I remove the cin.ignore(), the loop becomes infinite. Why is this? What can I do to make this into an elegantly functioning loop? Thank you.
In your non-integer branch you are invoking further cin methods so cin.good() gets reset to true.
You could change your code to something like this:
while(1) { // <<< loop "forever"
cout << "Please enter an integer.";
cin >> n;
if (cin.good())
{
if (n < 0) {cout << "Negative.";}
else { cout << "Positive."; break; }
} // ^^^^^ break out of loop only if valid +ve integer
else
{
cout << "Not an integer.";
cin.clear();
cin.ignore(INT_MAX, '\n'); // NB: preferred method for flushing cin
}
}
cout << "\ndone.";
or you can simplify it even further like this:
while (!(cin >> n) || n < 0) // <<< note use of "short circuit" logical operation here
{
cout << "Bad input - try again: ";
cin.clear();
cin.ignore(INT_MAX, '\n'); // NB: preferred method for flushing cin
}
cout << "\ndone.";
int n;
while (!(cin >> n)||n<0)//as long as the number entered is not an int or negative, keep checking
{
cout << "Wrong input. Please, try again: ";
cin.clear();//clear input buffer
}
//only gets executed when you've broken out of the while loop, so n must be an int
cout << "Positive.";
cout << "\ndone.";//finished!
Should do what you want.