C++ Perfect Number With Nested Loops Issue - c++

What I am trying to do is search for a perfect number.
A perfect number is a number that is the sum of all its divisors, such as 6 = 1+2+3.
Basically what I do here is ask for 2 numbers and find a perfect number between those two numbers. I have a function that tests for divisibility and 2 nested loops.
My issue is that I don't get any result. I've revised it & can't seem to find anything wrong. The compiler doesn't shoot out any errors.
What can be wrong?
#include <iostream>
using namespace std;
bool isAFactor(int, int);
int main()
{
int startval;
int endval;
int outer_loop;
int inner_loop;
int perfect_number = 0;
cout << "Enter Starting Number: ";
cin >> startval;
cout << "Enter Ending Number: ";
cin >> endval;
for(outer_loop = startval; outer_loop <= endval; outer_loop++)
{
for(inner_loop = 1; inner_loop <= outer_loop; inner_loop++)
{
if (isAFactor(outer_loop, inner_loop) == true)
{
inner_loop += perfect_number;
}
}
if (perfect_number == outer_loop)
{
cout << perfect_number << " is a perfect number." << endl;
}
else
{
cout << "There is no perfect number." << endl;
}
}
system("PAUSE");
return 0;
}
bool isAFactor(int outer, int inner)
{
if (outer % inner == 0)
{
return true;
}
else
{
return false;
}

inner_loop += perfect_number; should be perfect_number += inner_loop;.
There are other issues -- you need to reset perfect_number to zero in each outer loop, and you should presumably print the message "There is no perfect number." if none of the numbers in range is perfect, rather than printing it once for every number in range that is not perfect.
I'd advise that you rename perfect_number to sum_of_factors, outer_loop to candidate_perfect_number and inner_loop to candidate_factor, or similar.

after the if statement:
cout << perfect_number;
cout << outer_loop;
if (perfect_number == outer_loop)
{
cout << perfect_number << " is a perfect number." << endl;
}
and see what values they have
Updated:
What is the value of your endval? is 0?, and thats why the loop ends so early

Oh, so many issues.
The variable perfect_number never changes. Did your compiler flag
this?
The outer loop will be one more than the ending value when it exits;
did you know this?
You don't need to compare bool values to true or false.
You could simplify the isAFactor function to return (outer %
inner) == 0;.
You could replace the call to isAFactor with the expression
((outer % inner) == 0).

Related

Why is my C++ function skipping my IF statements?

So, let me preface that I am still learning C++ and would appreciate some guidance on what I am doing wrong.
My prompt is to write a function that continuously prompts a user for a valid age (between 0 and
100) and the function must only return the age to the caller of the function after a valid age is retrieved. AND For each function, you must declare the function using a function prototype before main and then define the function after main.
Here is my code,
#include <iostream>
using namespace std;
int num;
bool valid;
int validateInput()
{
cout << "Pick a number between 0 and 100" << endl;
cin >> num;
while(bool valid = false)
{
if(num <= 0)
{
cout << "Error: Number is invalid because it's too low" << endl;
bool valid = false;
return 0;
}
else if (num >= 100)
{
cout << "Error: Number is invalid because it's too high" << endl;
bool valid = false;
return 0;
}
else
{
cout << "You are " << num << " years old." << endl;
bool valid = true;
return 0;
}
}
}
int main()
{
validateInput();
return 0;
}
So I am trying to get my program to work but the IF statements keep getting skipped.
Am I misunderstanding something? Any and all help is very much appreciated.
EDIT: Thank you to Arvin and iammilind for your help.
I was able to fix the code so my while loop condition would actually trigger, moved my cout statements into the loop and so I wouldn't get infinite output.
My final working code looked like this.
#include <iostream>
using namespace std;
int num;
bool valid = false;
int validateInput()
{
while(!valid)
{
cout << "Pick a number between 0 and 100" << endl;
cin >> num;
if(num <= 0)
{
cout << "Error: Number is invalid because it's too low" << endl << endl;
bool valid = false;
}
else if (num >= 100)
{
cout << "Error: Number is invalid because it's too high" << endl << endl;
bool valid = false;
}
else
{
cout << "You are " << num << " years old." << endl;
bool valid = true;
return 0;
}
}
}
int main()
{
validateInput();
return 0;
}
You give a false value to the while loop that makes the while loop doesn't start the loop.
do this instead:
bool valid = false;
while (!valid){ // while valid is still false, do the loop
// your code here
}
Further explanation: You're currently using sentinel-controller loop
reference: https://simplecplusplus.wordpress.com/tag/sentinel-controlled-loop/
In order for while loop to start running, you've to provide the "true" condition to the while, and it will start looping until the condition turn out to false.
Programming tips for you: next time, you've to see the larger picture of your code every time you're trying to debugging. If you're sure the if-else code is running and have no problem, you have to enlarge your investigation for the bug, maybe it's the while loop that didn't work, not if-else. And if the while loop seems having no problem, maybe its the function or the caller of the function
while(bool valid = false) never allows the execution to enter the loop. Hence the if conditions are never called.
Use it as below:
while(valid == false) { // see '==' sign. `while(not valid)` is also fine
// ... your 'if' conditions
}
Actually you are creating a locally scope variable within while() by having a bool before it. So bool valid hides bool ::valid (declared outside).
Also, once the loop ends, you may want to reset it to false again. Otherwise this function will never be able to used again!
Using globals (bool valid) for such functionality is a bad design.

if....else executing in the same time . Looking this problem for first time. Please anybody make me understand

I was solving a problem . Where i was comparing two array ,one is int and other is string .
inside for loop everything was fine until i inserted a else condition.Before else condition for loop was just fine . it was giving equel index for two array . But after else condition it was giving both the condition together.
here are my code-
#include <iostream>
#include <string>
using namespace std;
int main()
{
int last_digit[] = {61, 71, 11, 21, 32, 19, 27, 31};
string places[] = {"Brasilia", "Salvador", "Sao Paulo", "Rio de Janeiro", "Juiz de Fora", "Campinas", "Vitoria", "Balo Horizonte"};
int digit;
cin >> digit;
for (int i = 0; i <= 7; i++)
{
if (digit == last_digit[i])
cout << places[i]<< endl;
else
cout << "Sorry! no number." << endl;
}
Now i want to print the array values as index which is right without the else condition. But i when an input isn't in the array the program should give else condition once. But it is giving both if else condition. Here are my output .
emamulhaqueemon#Emams-MacBook-Air snake % cd "/Users/emamulhaqueemon/main/snake/" && g++ test.cpp -o test && "/Use
rs/emamulhaqueemon/main/snake/"test
11
Sorry! no number.
emamulhaqueemon#Emams-MacBook-Air snake %
now why this is happening and how can i make this right .Please anybody give the answers.
Your loop currently does too much:
find digit in last_digit
print corresponding element according to found digit
print no matching elements (whereas you want to print when find fails).
You might split that in smaller parts.
With functions from std, you might do:
const auto it = std::find(std::begin(last_digit), std::end(last_digit), digit);
if (it == std::end(last_digit)) { // Not found
std::cout << "Sorry! no number." << std::endl;
} else { // Found
const auto index = std::distance(std::begin(last_digit), it);
std::cout << places[index] << std::endl;
}
Demo
Just place the output statement in the else part of the if statement outside the for loop. For example
bool found = false;
for (int i = 0; i <= 7; i++)
{
if ( digit == last_digit[i])
{
found = true;
cout << places[i]<< endl;
}
}
if ( !found )
{
cout << "Sorry! no number." << endl;
}
If the array last_digit does not contain duplicate values and you need to find only the first occurrence of the value digit in the array then the loop can look the following way
for (int i = 0; !found && i <= 7; i++)
{
if ( digit == last_digit[i])
{
found = true;
cout << places[i]<< endl;
}
}
if ( !found )
{
cout << "Sorry! no number." << endl;
}

Need help to stop program terminating without users consent

The following code is supposed to do as follows:
create list specified by the user
ask user to input number
3.a) if number is on the list , display number * 2, go back to step 2
3.b) if number isn't on the list, terminate program
HOWEVER step 3.a) will also terminate the program, which is defeating the purpose of the while loop.
here is the code :
#include <iostream>
#include <array>
using namespace std;
int main()
{
cout << "First we will make a list" << endl;
array <int, 5>list;
int x, number;
bool isinlist = true;
cout << "Enter list of 5 numbers." << endl;
for (x = 0; x <= 4; x++)
{
cin >> list[x];
}
while (isinlist == true)
{
cout << "now enter a number on the list to double" << endl;
cin >> number;
for (x = 0; x <= 4; x++)
{
if (number == list[x])
{
cout << "The number is in the list. Double " << number << " is " << number * 2 << endl;
}
else
isinlist = false;
}
}
return 0;
}
Please can someone help me to resolve this ?
I would suggest that you encapsulate the functionality of step 3 into a separate function. You could define a function as follows, and then call it at an appropriate location in the main function.
void CheckVector(vector<int> yourlist)
{
.... // Take user input for number to search for
.... // The logic of searching for number.
if (number exists)
{
// cout twice the number
// return CheckVector(yourlist)
}
else
return;
}
The same functionality can be implemented with a goto statement, avoiding the need for a function. However, using goto is considered bad practice and I won't recommend it.
Your issue is that you set isinlist to false as soon as one single value in the list is not equal to the user input.
You should set isinlist to false ay the beginning of your while loop and change it to true if you find a match.
Stepping your code with a debugger should help you understand the issue. I encourage you to try it.

Why are my if statements not working consistently?

I'm making a coin toss program for my c++ class and we are required to make a function that flips a coin and prints out if it is heads or tails, and print 10 per line. When I ran the program though the if statements I used to detect if the coin was heads or tails weren't enough to pick from the two.
#include <iostream>
#include <ctime>
using namespace std;
void coinToss(int times);
int main()
{
srand(time(0));
int times;
cout << "How many times would you like to toss the coin?" << endl;
cin >> times;
coinToss(times);
return 0;
}
void coinToss(int times)
{
int toss = 0, count = 0;
for(int i = 0; i < times;i++)
{
toss = rand()%2;
if(toss == 1)//Detects if coin is heads.
{
cout << "H";
}
if(toss == 0)//Detects if coin is tails.
{
cout << "T";
}
else //I had to include this for the program to run, further explanation below the code.
{
cout << "Ya done goofed.";
}
count++; //Counts to ten
if(count == 10) //Skips to the next line if the coin has been tossed ten times.
{
cout << endl;
count = 0;
}
}
}
At one point I replaced the heads or tails with "cout << toss;" and the only numbers returned were 1 and 0. I don't understand how if I'm getting only the two numbers I'm checking for some of them aren't being caught by my if statements.
To complete the assignment I've changed the second if statement into an else statement and everything seems peachy, but I'd really like to understand what's going on here.
What happens with your code is:
Is the result 1 ? Then print H. Keep going. Is the result 0 ? Then print T. Else, if it's not 0, print "Ya done goofed.".
You need to keep your if statements linked together:
if (toss == 1) {
cout << "H";
} else if (toss == 0) {
cout << "T";
} else {
cout << "Ya done goofed.";
}
You won't fall in the else case anymore and will be able to remove it.
As a sidenote, regarding your overall program structure: your coinToss function shouldn't do everything. Your code should be more splitted: a function which returns H or T, a function which calls this function X times as requested by the user and formatting the output would be a good start.
Another small note: your count variable, allowing you to add a new line every 10 flips, could be removed. i % 10 will give you the same result: every ten increments, i % 10 would be equal to 0.
You're probably printing the output properly, then terminating without writing a newline on the last line, and your shell prompts clearing back to the left margin and overwriting your output (clearing the rest of the line to boot). If you have less than 10 tosses, your only line of output may appear lost, otherwise it'll be the last line.
Try adding an extra std::cout << '\n'; before main returns.
(Separately, you can say std::cout << "HT"[rand() % 2];, or std::cout << (rand() % 2 ? 'H' : 'T'); and do away with the ifs, but it's no big deal... whatever's clearest for you at this stage)
Well, rand()%2 will produce only two numbers: 1 and 0, this seems to be in line with your task as a coin is a boolean number generator, isn't it? :)
Therefore this seems to do the job you are looking for:
#include <iostream>
#include <ctime>
using namespace std;
void coinToss(int times);
int main()
{
srand(time(0));
int times;
cout << "How many times would you like to toss the coin?" << endl;
cin >> times;
coinToss(times);
return 0;
}
void coinToss(int times)
{
int toss = 0, Count = 0;
for(int i = 0; i < times;i++)
{
toss = rand() % 2;
// Choose:
cout << ((toss) ? "H" : "T"); // if you want a character
// or
cout << toss; // if you want the number
Count++; //Counts to ten
if(Count == 10) //Skips to the next line if the coin has been tossed ten times.
{
cout << endl;
Count = 0;
}
}
}
if(toss == 1)//Detects if coin is heads.
{
cout << "H";
}
else if(toss == 0)//Detects if coin is tails.
{
cout << "T";
}
You need to use else-if statement. You also need not use else after the toss==0 because rand()%2 will either be 0 or 1. There is no third option.
rand() returns a pseudo-random integral number in the range between 0 and RAND_MAX. And, rand() % 2 will be 0 or 1. So, there would be:
if(toss == 1)//Detects if head
{
cout << "H";
}
else // tail
{
cout << "T";
}
I don't think there is anything wrong with this. Well not that I can see... If I add some debug then I see what I think you're expecting...
#include <iostream>
#include <ctime>
using namespace std;
void coinToss(int times);
int main() {
srand(time(0));
int times;
cout << "How many times would you like to toss the coin?" << endl;
cin >> times;
coinToss(times);
return 0;
}
void coinToss(int times) {
int toss = 0, count = 0;
for(int i = 0; i < times;i++) {
toss = rand() % 2;
cout << "Toss: " << toss << endl;
if(toss == 1)//Detects if coin is heads.
{
cout << "H (" << toss << ")" << endl;
}
if(toss == 0)//Detects if coin is tails.
{
cout << "T (" << toss << ")" << endl;
}
count++; //Counts to ten
if(count == 10) //Skips to the next line if the coin has been tossed ten times.
{
//cout << endl; count = 0;
}
}
}
And compile it
g++ coin_toss.cc
And run it
./a.out
How many times would you like to toss the coin?
4
Toss: 1
H (1)
Toss: 0
T (0)
Toss: 0
T (0)
Toss: 0
T (0)
Then this is exactly what I expect or am I missing something?
You don't need an "if else if" statement.
You can also use a switch:
switch( rand() % 2 )
{
case 0:
cout << "T";
break;
case 1:
cout << "H";
break;
default:
cout << "oops you goofed!;
}
// continue within for loop
If you "forgot" the break after case 1 you would again get the "oops you goofed!" message after each head toss.

Why do I get the error "Floating point exception"?

I am trying to write a code that finds perfect numbers lower than the user's input.
Sample of correct output:
Enter a positive integer: 100
6 is a perfect number
28 is a perfect number
There are no more perfect numbers less than or equal to 100
But when I run my code, I get the error Floating point exception
and can not figure out why. What am I doing wrong?
Here is my code:
#include <iostream>
using namespace std;
bool isAFactor(int, int);
int main(){
int x, y;
int countOut, countIn;
int userIn;
int perfect = 0;
cout << "Enter a positive integer: ";
cin >> userIn;
for(countOut = 0; countOut < userIn; countOut++){
for(countIn = 1; countIn <= countOut; countIn++){
if(isAFactor(countOut, countIn) == true){
countOut = countOut + perfect;
}
}
if(perfect == countOut){
cout << perfect << " is a perfect number" << endl;
}
perfect++;
}
cout << "There are no more perfect numbers less than or equal to " << userIn << endl;
return 0;
}
bool isAFactor(int inner, int outer){
if(outer % inner == 0){
return true;
}
else{
return false;
}
}
The arguments are just swapped. You are calling the function as isAFactor(countOut, countIn) when you should be calling with isAFactor(countIn, countOut)
To clarify #Aki Suihkonen's comment, when performing:
outer % inner
If inner is zero, you will get a divide by zero error.
This can be traced backward by calling isAFactor(0, 1).
It is in your for loop in main.
The first parameter to isAFactor(countOut, countIn) is assigned in the outermost for loop:
for (countOut = 0; ...
Notice the value you are initializing countOut with.
Edit 1:
Change your `isAFactor` function to:
if (inner == 0)
{
cerr << "Divide by zero.\n";
cerr.flush();
return 0;
}
if (outer % inner ...
Place a breakpoint at either cerr line above.
When the execution stops there, look at the Stack Trace. A good debugger will also allow you to examine the parameter / values at each point in the trace.