C++ Program for Prime Factors - c++

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).

Related

c++ why the second input is ignored?

I need to check whether digit was entered and if not, ask for correct input.
Second input is ignored for some reason.
(There should be "while" instead of "if" in the final version, but I replaced it to "if" for debug to avoid eternal loops)
#include <iostream>
int main()
{
int number = 0;
std::cout << "Please enter some digit:\n";
std::cin >> number;
if (!isdigit(number))
{
std::cout << "Wrong input, please enter digit\n";
std::cin >> number;
}
}
There is no point in using isdigit() on an int, it only makes sense to use it with a char, as it looks for characters between '0'..'9', not integers between 0..9.
If cin >> number fails to read in a valid integer, it will put the stream into a failure state, which blocks further input. You must clear() that state, and also ignore() the erroneous input, before you can read in further input.
Try something more like this:
#include <iostream>
#include <limits>
int main()
{
int number;
std::cout << "Please enter a single digit:\n";
do
{
if (std::cin >> number)
{
if (number >= 0 && number <= 9)
break;
std::cout << "Wrong input, please enter a single digit\n";
}
else
{
std::cout << "Wrong input, please enter a valid digit\n";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
}
while (true);
std::cout << "You entered: " << number << std::endl;
}

Which flag in cin turns to false when you enter a wrong type input [duplicate]

I want to check if the input is valid, but when i do run this code I see that it checks only input for charcters. If i input a float number it will take it and going to use like integer without fractional part.
#inclide <iostream>
using namespace std;
...
int n;
cout << "Your input is: "<<endl;
cin >> n;
while (cin.fail()) {
cout << "Error. Number of elements must be integer. Try again: " << endl;
cin.clear();
cin.ignore(256, '\n');
cin >> n;
}
...
`
So, how to make this code see if the input is float?
You can try to convert the input string to a int using a std::istringstream. If it succeeds then check for eof() (after ignoring blank spaces) to see if the whole input was consumed while converting to int. If the whole input was consumed then it was a valid int.
Something a bit like this:
int input_int()
{
int i;
// get the input
for(std::string line; std::getline(std::cin, line);)
{
// try to convert the input to an int
// if at eof() all of the input was converted - must be an int
if(!line.empty() && (std::istringstream(line) >> i >> std::ws).eof())
break;
// try again
std::cout << "Not an integer please try again: " << std::flush;
}
return i;
}
int main()
{
std::cout << "Enter an integer: " << std::flush;
std::cout << "i: " << input_int() << '\n';
}
Building on Raindrop7's solution, here's the full code to do what you need:
#include <cstdio>
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
double m;
cout << "Your input is: "<<endl;
cin >> m;
while (cin.fail() || (m-floor(m)))
{
cout << "Error. Nubmer of elements has to be integer. Try again: " << endl;
cin.clear();
cin.ignore(256, '\n');
cin >> m;
}
int n = (int)m;
return 0;
}
Here's a sample output:
Your input is:
2.7
Error. Nubmer of elements has to be integer. Try again:
erer
Error. Nubmer of elements has to be integer. Try again:
2
The code below should be able to do what you are hoping to achieve:
#inclide <iostream>
using namespace std;
int n;
cout << "Your input is: "<<endl;
while (!(cin >> n) || cin.get() != '\n') {
cout << "Error. Number of elements must be integer. Try again: " << endl;
cin.clear();
cin.ignore(256, '\n');
}
The program asks the user to re-enter an integer if either of the following happens:
If the program is unable to extract an integer from the std::cin stream. (For example, when a character or string is entered by the user)
If, after an integer is extracted successfully, the next character in std::cin is not the new line '\n' character. (For example, when a number with a decimal point like 1.1 is entered, or when an integer followed by a character like 1a is entered.)

About loop, it has some errors

I try to identify if a number is an interger or not.
When I run this, I enter a number, such as 5.5, it shows "5.5 is not int. Please try again: ". Then I enter the letter, such as 'a', it shows "5.5 is not int. Please try again: ". The letter 'a' is a character, not integer, I think it should go to the second case and must show "No letter please", but it isn't.
When I first enter a letter, such as 'D', the program run "Please no letter" unlimited times. I wants it shows "Please no letter" but only once, then I can enter another number in this loop.
How can I fix these errors?
while (true) {
while ((num) != static_cast<int>(num)) {
cout << "\t" << num << " is not int. Please try again: ";
cin >> num;
cin.clear();
cin.ignore(80, '\n');
}
while (!(cin >> num)) {
cout << "\tNo letter please: ";
cin >> num;
cin.clear();
cin.ignore(80, '\n');
}
cout << "Good! " << num << " is an int!\n\n";
}
You can do in this way. Enter a string from user. Count the number of characters in that string. If that is equal to string length it is a valid positive integer. For negative integers just check if the number of digits is one less than size of string and string is starting with 0.
#include <iostream>
using namespace std;
int main()
{
string s;
while(true)
{
cin>>s;
int i,no_of_digits=0;
for(int i=0;i<s.length();i++)
{
if(isdigit(s[i]))
no_of_digits++;
}
if(no_of_digits == s.length() || (no_of_digits == s.length()-1 && s[0]=='-'))
{
cout<<"Good "<<s<<" is an Integer.";
break;
}
cout<<s<<" is not a valid Integer!\nPlease Enter again\n";
}
return 0;
}
The best way to parse string in cpp. It's to use stringstream or use sto* series functions of cpp11.
There are already some good answer here.

fixing an unintentional infinite loop

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.

CIN within certain range

I am trying to make a cin where the user can only enter 0 to 1. If the user doesnt enter those numbers then he should get an error saying "Please enter within the range of 0 to 1."
But its not working.
What am i doing wrong?
int alphaval = -1;
do
{
std::cout << "Enter Alpha between [0, 1]: ";
while (!(std::cin >> alphaval)) // while the input is invalid
{
std::cin.clear(); // clear the fail bit
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // ignore the invalid entry
std::cout << "Invalid Entry! Please Enter a valid value: ";
}
}
while (0 > alphaval || 1 < alphaval);
Alpha = alphaval;
Try this:
int alphaval;
cout << "Enter a number between 0 and 1: ";
cin >> alphaval;
while (alphaval < 0 || alphaval > 1)
{
cout << "Invalid entry! Please enter a valid value: ";
cin >> alphaval;
}
If you want to trap empty lines I'd use std::getline and then parse the string to see if the input is valid.
Something like this:
#include <iostream>
#include <sstream>
#include <string>
int main()
{
int alphaval = -1;
for(;;)
{
std::cout << "Enter Alpha between [0, 1]: ";
std::string line;
std::getline(std::cin, line);
if(!line.empty())
{
std::stringstream s(line);
//If an int was parsed, the stream is now empty, and it fits the range break out of the loop.
if(s >> alphaval && s.eof() && (alphaval >= 0 && alphaval <= 1))
{
break;
}
}
std::cout << "Invalid Entry!\n";
}
std::cout << "Alpha = " << alphaval << "\n";
return 0;
}
If you want a different prompt on error then I'd put the initial prompt outside the loop and change the inner prompt to what you prefer.
Week one of C++, starting with Peggy Fisher's Learning C++ on Lynda.com.
This is what I came up with. Love to receive feedback.
int GetIntFromRange(int lower, int upper){
//variable that we'll assign input to
int input;
//clear any previous inputs so that we don't take anything from previous lines
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
//First error catch. If it's not an integer, don't even let it get to bounds control
while(!(cin>>input)) {
cout << "Wrong Input Type. Please try again.\n";
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
//Bounds control
while(input < lower || input > upper) {
cout << "Out of Range. Re-enter option: ";
cin.ignore(numeric_limits<streamsize>::max(), '\n');
//Second error catch. If out of range integer was entered, and then a non-integer this second one shall catch it
while(!(cin>>input)) {
cout << "Wrong Input Type. Please try again.\n";
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
}
//return the cin input
return input;
}
As the exercise was to order Hamburgers, this is how I ask for the amount:
int main(){
amount=GetIntFromRange(0,20);
}