fixing an unintentional infinite loop - c++

when i input a random number like 63453462 it responds with "invalid number" but in an infinite loop but if i put a number like 2,000,002 it just says invalid number with no loop. I need help with not making an infinite loop when someone inserts a random number like 2145345665465.
#include <iostream>
using namespace std;
int main ()
{
int sum , input , number;
cout << "Enter any positive integer that is less than or " ;
cout << "equal to 2,000,000 to determine if it is divisible by 11.";
cout << endl;
cout << "If the number is greater than 99, we use Dodgsons's rule";
cout << endl;
cout << "which determines if it is a factor or not.\n";
cout << endl;
cin >> input;
while ((input < 1) || ( input > 2000000 ))
{
cout << "Invalid number detected, please enter a positive integer.\n";
cin >> input;
}
number = input;
while ((input>=100) && (input < 2000000))
{
sum = input % 10;
input = input /10 - sum;
cout << input << endl;
}
if (input % 11 == 0)
cout << "the number is divisible by 11." << endl;
else
cout << "the number is not divisible by 11." << endl;
system ("Pause");
return 0;
}

while ((input < 1) || ( input > 2000000 ))
{
cout << "Invalid number detected, please enter a positive integer.\n";
cin >> input;
cin.clear();
}
cin.clear() will clear any previous state that cause the infinite loop.

You need to properly check whether your input operation succeeded. If you enter something that cannot be parsed as an integer, or some value that is more than INT_MAX or less than INT_MIN, then after
cin >> input
the stream std::cin will enter a failed state, that means the failbit is set. After that, each following input operation will also fail, unless you take care of it.
The usual approach here is to clear the input buffer (with the input that could not be handled) and just try again:
while (not (cin >> input) or not is_valid(input)) {
cout << "Invalid input, try again" << endl;
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
cin.clear();
}
This first does the input operation (cin >> input) and checks whether it not succeeded, and only if that is not true (i.e. the input operation succeeded) checks whether the input is not valid using some is_valid function. In that case an error is printed, all characters up to and including the next newline are removed from the stream, and the failbit is cleared, in order to allow a new take on getting valid input.
Note, that having two variables of the same type and doing
number = input;
is useless here, you can directly read into number (which is more appropriately named) and drop the variable input all together.

Related

Why am I getting a "1" output in between the other output lines?

I am very new to C++, and I am trying to make a simple number reading program, and it is functional. However, I keep getting a '1' input in between my other output lines. How can I remove these 1s?
Here is my code:
#include <stdio.h>
#include <iostream>
using namespace std;
int main()
{
printf("\nThe following program should enter integer numbers until a negative number.\n");
printf("The output is the smallest number input as well as the number of numbers.\n\n");
printf("Please enter a number -----> ");
int n = 0;
int num;
cin >> num;
int smallest = num;
while (num >= 0)
{
n++;
if (num < smallest)
{
int smallest = num;
}
cout << "Please enter another number -----> " << (cin >> num) << endl;
}
while (num < 0)
{
cout << "Negative number entered. Calculating Results...\n\n";
cout << "Of " << n << " numbers read, the smallest number is " << smallest << ".\n";
return 0;
}
}
And the output looks like this (I randomly input some test numbers):
The following program should enter integer numbers until a negative number.
The output is the smallest number input as well as the number of numbers.
Please enter a number -----> 3
Please enter another number -----> 4
1
Please enter another number -----> 8
1
Please enter another number -----> -1
1
Negative number entered. Calculating Results...
Of 3 numbers read, the smallest number is 3.
'''
How do I remove these 1s, and why are they happening?
(cin >> num)
This expression does two things:
The cin input stream waits for user input and puts that value into num.
The operator overload for >> on an istream returns a istream&, a reference to the cin instance.
(This is why you can repeat the >> operator on one line to get multiple values.)
That expression is in a place where the cout << operator is expecting an argument, so the conversion from istream& to some sort of printable character is resulting in a 1 being added to the cout stream.
The reason the 1 is on a new line is because the terminal/console you're using requires you to use the Enter key (which adds a new line) to enter a value.
I tried this in my c++ console, and had to make a change in line 25. Instead of -
cout << "Please enter another number -----> " << (cin >> num) << endl;
I used this -
cout << "Please enter another number -----> ";
cin >> num;
And there were no explicit error messages. Also, no 1s.
I am a bit concerned about the actual code though. The logic is not correct.
How was you able to compile this code?
Doc.cpp:26:60: error: no match for ‘operator<<’ (operand types are ‘std::basic_ostream’ and ‘std::basic_istream::__istream_type {aka std::basic_istream}’)
cout << "Please enter another number -----> " << (cin >> num) << endl;
I have to change this line:
cout << "Please enter another number -----> " << (cin >> num) << endl;
into this:
cout << "Please enter another number -----> ";
cin >> num;
cout << endl;
in order to make the code compilable, at least for me.
Also, the last while loop is unnecessary, since if num is not bigger or equal to zero, it could only be a negative number.

Trying to validate input in C++

The idea behind this code in c++ is to calculate the sum of all the entered numbers. When the user enters 0, the program should stop. This part of the code is working as I intended, but I'd like to include a variant which recognizes that a character different than a float number has been entered, ignore it in the calculation and allow the user to continue entering float numbers. At the moment, entering anything else but a float number stops the program.
I know there's a "if (!(cin >> numb))" condition, I've tried parsing it in different places in the code, but I can't figure out how to force the program to ignore these invalid inputs. I would be very grateful for any help.
#include <iostream>
#include <stdlib.h>
using namespace std;
float numb; float sum=0;
int main()
{
cout << "This app calculates the sum of all entered numbers." << endl;
cout << "To stop the program, enter 0." << endl << endl;
cout << "Enter the first number: ";
cin >> numb;
while(true)
{
sum += numb;
if (numb!=0)
{
cout << "Sum equals: " << sum << endl << endl;
cout << "Enter another number: ";
cin >> numb;
}
else
{
cout << "Sum equals: " << sum << endl << endl;
cout << "Entered 0." << endl;
cout << "Press Enter to terminate the app." << endl;
exit(0);
}
}
return 0;
}
You have three options:
trial and error: try to read a float, and in case of error clear the error flag, ignore the bad input and read again. The problem is that you don't know really how many of the input is to be ignored.
read strings: read space delimited strings, try to convert the string using stringstream, and just ignore the full string in case of error. The problem is that if the input starts with a valid float but then contains invalid characters (e.g. 12X4), the invalid part will be ignored (e.g. X4)
control parsing: read space delimited strings, try to convert the string using std::stof(), and check that all characters of the string where successfully read
Here the second approach, with a slightly restructured loop, so that a 0 entry will lead to exiting the loop and not the full program:
string input;
while(cin >> input)
{
stringstream sst(input);
if (sst>>numb) {
sum += numb;
cout << "Sum equals: " << sum << endl << endl;
if (numb==0)
{
cout << "Entered 0." << endl;
break; // exits the while loop
}
cout << "Enter another number: ";
}
else
{
cout << "Ignored entry "<<input<<endl;
}
}
cout << "Press Enter to terminate the app." << endl;
Online demo
If you prefer a more accurate parsing, consider something like:
size_t pos=0;
float xx = stof(input, &pos );
if (pos!=input.size()) {
cout << "error: invalid trailing characters" <<endl;
}
You have to clear the failbit after a failed read. After that, you can read in the invalid stuff into a string (that you just ignore). This function will read in values and add them up until it encounters a 0 or the end of the input stream.
int calc_sum_from_input(std::istream& stream) {
int sum = 0;
// If it couldn't read a value, we just read the thing into here
std::string _ignored;
while(stream) // Checks if the stream has more stuff to read
{
int value;
if(stream >> value)
{
if(value == 0) // Exit if it read the value 0
break;
else
sum += value; // Otherwise update the sum
}
else {
// Clear the failbit
stream.clear();
// Read ignored thing
stream >> _ignored;
}
}
return sum;
}
The logic is basically:
set the initial sum to 0
check if there's stuff to read
if there is, try reading in a value
if successful, check if the value is 0
if it's 0, exit and return the sum
otherwise, add the value to the sum
otherwise, clear the failbit (so that you can read stuff in again) and read the bad value into a string (which gets ignored)
otherwise, return the value

C++ Program for Prime Factors

I'm trying to build a program that asks to user to input a positive integer and then the prime factors of this number are outputted. I'm giving the user three attempts to enter a valid input or the program ends. So any negative integers and non integers as well as other characters such as letters will give an error message. I'm nearly there but my output won't behave as I want. It treats decimal numbers as integers and negative numbers aren't returning the error.
#include <iostream>
#include <iomanip>
#include <cmath>
#include <stdio.h>
using namespace std;
int main()
{
int num,i,flag,n;
//executes loop if the input fails (e.g., no characters were read)
while (cout << "Enter a number: " && !(cin >> num))
{
cin.clear(); //clear bad input flag
cin.ignore(numeric_limits<streamsize>::max(), '\n'); //discard input
cout << "Invalid input, please re-enter: \n";
}
i=2;
n=num;
cout<< "\nThe Prime factors of "<< num << " are:"<< endl;
while(i<=num)
{
flag=0;
while(n%i==0)
{
n=n/i;
flag++;
}
if(flag>0)
{
cout <<i<< endl;
}
++i;
}
system("PAUSE");
return 0;
}
You are not getting an error for entering a negative number as you are not checking for that in you input validation. You could add into your while condition to check for a negative output as:
while (cout << "Enter a number: " && (!(cin >> num) || num <= 0))
The reason you do not catch input of a decimal number is cin successfully converts and stores the input up to the decimal point and then stops, leaving the remainder of the input in the buffer. We can see that with:
#include <iostream>
int main()
{
int foo;
double bar;
std::cin >> foo;
std::cin >> bar;
std::cout << foo << std::endl;
std::cout << bar;
}
Input:
5.82
Output:
5
0.82
Live Example
You could include a check in your while loop condition to see if there is more input waiting in the stream with
while (cout << "Enter a number: " && (!(cin >> num) || num <= 0 || cin.get() != '\n'))
As for looping only three times you can add a counter to the program and increment the counter each time the body of the loop executes. Once the counter gets to 3 then you would exit the program
int counter = 0;
while (cout << "Enter a number: " && (!(cin >> num) || num <= 0 || cin.get() != '\n'))
{
if (counter == 3)
return 0; // exit
cin.clear(); //clear bad input flag
cin.ignore(numeric_limits<streamsize>::max(), '\n'); //discard input
cout << "Invalid input, please re-enter: \n";
counter++;
}
!(cin >> num) is only true when cin fails to insert the input character data into num, which is an int. Both negative integers (like -12) and decimal quantities (like 3.14) can be stuffed into a signed int. The decimal quantity works because floats can be coerced into ints by truncation.
To do what you want, you need to first capture your console input as a string, then attempt to parse out a positive integer. Take a look at How do I check if a C++ string is an int? and also boost::lexical_cast (if boost is an option).

How do i check if input is an int in C++?

If the input is an integer, I want to set it equal to an integer variable.
If the input is a string, I will want to set it to a string variable, and later check if the string is "quit".
I don't know how to check it. I've looked for a built in function and found nothing.
while (true) {
int numberEntered;
string stringEntered;
cout << "enter a number to see if it is greater than 5: \n or enter \'quit\' to exit the program";
//I don't know what to do below here
cin >> ;
if (stringEntered == "quit") {
break;
}
if (numberEntered > 5) {
cout << "that number is greater than 5" << endl;
}
else {
cout << "not greater than 5" << endl;
}
}
cin >> numberEntered;
if (!cin.fail())
{
...
It may be more idiomatic to use:
if (cin >> numberEntered)
David S.'s answer is good. If you want to tidily handle garbage being entered after the line, here is another option (this is more complicated for your situation, but if you later want to expand your program to handle a lot of different input, then this way may come out to be simpler).
while( true )
{
string stringEntered;
cout << "enter a number to see if it is greater than 5: \n or enter \'quit\' to exit the program: " << flush;
// read the whole line, this ensures no garbage remains in the input stream
getline(cin, stringEntered);
if ( stringEntered == "quit" )
break;
// this checks that a number was entered and nothing else
istringstream iss(stringEntered);
int numberEntered;
char ch;
if ( !(iss >> numberEntered) || (iss >> ch) )
{
cout << "please try again. ";
continue;
}
// process the number
cout << "that number is " << (numberEntered > 5 ? "" : "not ")
<< "greater than 5." << endl;
}
You may need #include <sstream>.

While Loop with LCV of cin won't exit in C++

This is hw. I have asked my professor why the following code won't exit the while loop, and he/she couldn't tell me. My understanding is that once the input stream has no more values to read, the cin will return a value of false, and should cause the while loop to exit. Mine does not. It seems to keep read the input values (a set of integers) process through the loop, then wait for more input. Can anyone tell me why? Below is the code.
# include <iostream>
using namespace std;
int main()
{
int iEvenSum = 0;
int iOddSum = 0;
int iNum;
// prompt user
cout << "Input any set of integers, separated by a space:\n";
cin >> iNum;
cout << "You input: ";
while (cin)
{
cout << iNum << " ";
if (iNum % 2 == 0)
iEvenSum = iEvenSum + iNum;
else
iOddSum = iOddSum + iNum;
cin >> iNum;
}
cout << "\n\nThe sum of Even numbers is " << iEvenSum << "." << endl;
cout << "The sum of Odd numbers is " << iOddSum << "." << endl;
return 0;
}
while(cin) remains true as long as the cin stream is ok and becomes false if cin encounters an end of file character or an error.
In your case, while(cin) will keep on reading the numbers until it encounters an EOF character or an error. Type Ctrl-D when you don't have any more input numbers and it should quit the while loop