Hello people!

I am a beginner trying to teach myself C++. If you guys could help or suggest me something I would greatly appreciate it! Sorry for my English!

My program determines if the entered number is prime or perfect.
I have a few problems with it. I would really want to not use breaks or functions in this program. I have spent hours on it and I really would like it to work the way it is supposed to. :)

1) I have no idea why the program won't output the entered number in the prime spot when the number is not perfect nor prime.

This program will determine if your entered number is a perfect
or a prime number, and what are it's factors.

Please enter any positive number between 1 and 1000.

9

9 is not a perfect number.

 is not a prime number.


Do you want to find the value of another character? (y/n)

n
Press any key to continue . . .

2) The program doesn't output the numbers that are not prime.

3) When I input a perfect number for a first time it says that it is a perfect number, but when I continue the program and input another perfect number without exiting the program, it says that is not a perfect number.

Here is an example, both 6 and 28 are perfect numbers.

This program will determine if your entered number is a perfect
or a prime number, and what are it's factors.

Please enter any positive number between 1 and 1000.

6

6 is a perfect number.

 is not a prime number.


Do you want to find the value of another character? (y/n)

y
This program will determine if your entered number is a perfect
or a prime number, and what are it's factors.

Please enter any positive number between 1 and 1000.

28

28 is not a perfect number.

 is not a prime number.


Do you want to find the value of another character? (y/n)

n
Press any key to continue . . .

4) I would like to output a list of divisors of non-prime numbers and a list of divisors of perfect numbers, and output about 5-10 of them per line, but I really have no idea how to do it.

Here is my source code.
Thank you! :)

#include <iostream>
#include <string>
using namespace std;

int num, i=1, sum=0;
char choice;
bool prime, perfect;

int main()
{

do{                                 // looping the program back to the beginning

cout << "This program will determine if your entered number is a perfect\n" <<
        "or a prime number, and what are it's factors.\n\n" <<    // tells what the program does
        "Please enter any positive number between 1 and 1000.\n"<< endl;  // asking the user to input a number
cin >> num;

    if (num >= 1 && num <= 1000) // checks if number is within the range 
    {

//  This part determines wheter the entered number is a perfect number.

        while(i<num)             // checks if the i is smaller than the entered number
         {
            if(num%i==0)            // checks if the entered number devided by i is equal to 0
                sum=sum+i;          // adds i to the sum
                       i++;         // increments i by 1
         }

  if(sum == num)                    // checks if the sum is equal to the entered number
         cout << "\n" << num  <<  " is a perfect number." << endl; // message for a perfect number
  else                              
         cout << "\n" << num << " is not a perfect number." << endl; // message for a not perfect number

//  This part determines wheter the entered number is a prime number.
    prime = true;                       // starts as a prime number
if (num == 1)                           // 1 is not a prime
    prime = false;                      // sets the prime flag to false
else if (num == 2)                      // 2 is a prime 
    prime = true;                       // sets the prime flag to true
else if (num % 2 == 0)                  // if it divides evenly by 2 it's not a prime
    prime = false;                      // sets the prime flag to false

for (int x = 3; x<= (num/2); x+=2)       // starts with 3 and increases by 2 every time 
{                                       // because multiples of 2 are never prime
    if (num % x == 0)                   // checks if the remainder is equal to 0
    {
        prime = false;                  // sets the prime flag to false
    }
}
        if(prime == true)               // if the number is prime it outputs
        {
            cout << "\n" << num << " is a prime number." << "\n" << endl; // message for a prime number
        }

        if(prime == false)              // if the number is not prime it outputs
        {
            cout << "\n" << " is not a prime number." << "\n" << endl; // message for a not prime number
        }
    }

    else
    {
        cout << "\n" << "Number is not within range, please try again."<<endl; // error message for a number out of the range
    }

    cout << "\n" <<  "Do you want to find the value of another character? (y/n)\n" // message about restarting the program
         << endl;     

cin >> choice;                          // inputing the choice character
}while(choice !='n');                   // looping the program back to the beginning 

system("pause");

return 0;
}

Here is your solution just see the logic behind the program and if you have any other problem in your learning please contact me i am here for your help. thank you.

#include<stdio.h>
#include<iostream.h>
#include<stdlib.h>
#include<conio.h>

void main()
{
    int num=0,i,flag=0,div=0;


    cout<<"Enter a Number: ";
    cin>>num;


    for(i=2;i<num;i++)
    {

        if((num%i)==0)
        {
            flag++;
        }

    }
    if(flag==0)
    {
        cout<<"number is prime";
    }
    else
    {
        cout<<"number is not prime";
    }

    for(i=1;i<=num;i++)
    {
        if((num%i)==0)
        {
            div=div+i;
        }

    }
    div=div/2;
    if(div==num)
    {
        cout<<"\nnumber is perfect";

    }
    else
    {
        cout<<"number is not perfect";
    }






}

Edited 3 Years Ago by veducator

Comments
Spponfeeding.

Thanks for the help! Do you have any idea how to solve the third and forth problem?

For the third problem you need to initialize sum as 0 in 'do section'.It's means do{ sum =0; }. just see the line number 5 in your program coding. when you first time run the program its 0 but when you run it one more time the value of sum is not 0 its 6. thats why you face this problem.

@Hajkmusic:
I'd recommend breaking your program down into separate functions, making it more modular and easier for you to test and debug. The main() function should control the main program loop and user input, then you should perhaps have two bool functions to test for prime and perfect numbers. You can call these functions from main to test the numbers entered by the user.
e.g.

bool IsPrime(int num);
bool IsPerfect(int num);

I won't write the functions for you, but I'm sure you can manage to work it out from the two prototypes listed above. There's not much more involved than moving some existing code out of main and into the bodies of the functions! ;)

Regarding problem 3, the problem with your perfect number test:
Referring to your original code, the global variables 'i' and 'sum' are the cause of the problem.

'i' and 'sum' are given their initial values at their point of declaration (as globals, outside of main). Then, the first time through the main program loop, when you perform your first perfect number test, their values are modified. But their values are not reset/reinitialised afterwards. So because they are global rather than local; they hold their previous values the next time through the loop. So the next time you go through the main loop and you enter another number, the perfect number test will not give the results you expect because 'i' and 'sum' have not been reinitialised, they still hold their previously modified values.

The lesson here is that 'i' and 'sum' do not need to be global variables. They are only used by the while loop used in your perfect number test, so they really only need to be declared and initialised just before they are used.

In fact, for this particular program there is no need for any global variables at all. When used indiscriminately, global variables can be a source of tricky bugs, especially if you have lots of other functions which modify them. It's easy to lose track of where and when globals variables are modified. Even in a simple program, as you have already discovered! ;)

In other words, all of the global variables you have declared should be declared locally, where they are used!

Also, in your primality test, you don't need to test by dividing num by each number up to num (as posted by veducator), or even half the number (as used by you). You only need to test as far as the square root of the number.
e.g.

int limit = static_cast<int>(sqrt(static_cast<float>(num)));
for(int x=3; x<=limit; ++x)

NOTE: To use sqrt in C++ you must #include the header <complex> or <cmath>.
Also sqrt deals with real numbers (float/double etc), but you are using int values. So in the above snippet, we're casting num to float in the call to sqrt and casting the returned value back to int and assigning that to an int variable called limit. Then you test num against values of x from 3 to the calculated limit.

Regarding the 4th, divisor related problem: You could add an additional function to calculate and output the divisors for the user entered number. You simply need to determine all of the values that the number divides by exactly. And if you only need the prime divisors, that should be simple enough to calculate too. I'll leave that for you to work out, but post some more code if you get stuck!

So to sum up:
1. Break your program into separate functions to make it more modular and easier for you to test/debug.
2. Declare variables in the scope in which they are used. Make them as localised as possible and avoid global variables unless absolutely necessary (HINT: Globals are NOT required in this program!). Avoiding globals will help to prevent careless bugs like the one with your perfect number test.

Cheers for now,
Jas.

p.s. @Veducator:
You don't need all of those C headers in your code. From the looks of your code, I'm guessing you're using an old Borland compiler. But regardless, the only header you need there is iostream.h for the C++ io stuff. The others are not required! :)

Edited 3 Years Ago by JasonHippy

@JesonHippy I know that in cpp only iostream.h header file required. and hajkmusic is begenner in cpp so I think he can't understand the about function and class in cpp. That why I write code in simple way so he can understand logic behind the program.

veducator: Please use the modern C++ headers in the future. The C++98 standard removed the .h extensions from all standard headers, such that <iostream.h> (for example) is now just <iostream>. Similarly, the standard headers for the C standard libraries to be prepended with a c, for example, <stdio.h> is now <cstdio>. Do not use the old style headers anymore, and do not use any compilers that don't support the new headers. The standard is now 15 years old, and there is no reason to use anything older than that.

On a related note, the <conio.h> header isn't standard, it is strictly a DOS library and has long since been phased out. DO NOT USE IT, ever, for any purposes at all.

If you're in a course that requires the use of older compilers (Turbo C++ being the usual suspect), leave the course, as you are being taught useless information. I know that there are several countries where the national education system has standardized on Turbo C++, but the only way it will get modernized is if the students get involved and demand a better education. The students of India and Pakistan are getting a raw deal enough as it is, with a system more interested in test scores and rote 'learning' than actual teaching; they don't need archaic systems rammed down their throats.

(Not that C++ is a good choice for a first language, anyway, but that's another debate entirely.)

Edited 3 Years Ago by Schol-R-LEA

@JasonHippy I put num and i right next to the loops but it didn't change anything :(
Could you please help me reset the values? Also I have no idea how to write the function for divisors, could you please give me some example or something? Thank you so much for your help! I really appreciate that :))))

int i, num, sum=0;
char choice;
bool prime, perfect;

int main()
{
    num = 0;
do{                                 // looping the program back to the beginning

cout << "This program will determine if your entered number is a perfect\n" <<
        "or a prime number, and what are it's factors.\n\n" <<    // tells what the program does
        "Please enter any positive number between 1 and 1000.\n"<< endl;  // asking the user to input a number
cin >> num;

    if (num >= 1 && num <= 1000) // checks if number is within the range 
    {

//  This part determines wheter the entered number is a perfect number.
        i=1;
        while(i<num)             // checks if the i is smaller than the entered number
         {
            if(num%i==0)            // checks if the entered number devided by i is equal to 0
                sum=sum+i;          // adds i to the sum
                       i++;         // increments i by 1
         }

Yes. You reset the value of i, but the value of sum is not being reset.

Once again, put the code for the perfect number and prime number tests into separate functions and lose all of the global variables. You don't need global variables in this program. Declare them where they are needed!

For example, your perfect number code can be refactored into a separate function which takes an int as a parameter and returns a bool to indicate whether a number is perfect or not.
e.g.

///////////////////////////////////////////////////////////////
/// Test whether a number is perfect
///////////////////////////////////////////////////////////////
/// \param <num> number to test
/// \return <bool> true=perfect, false=not perfect
///////////////////////////////////////////////////////////////
bool IsPerfect(int num)
{
    int i=1;
    int sum=0;
    while(i<num)
    {
        if(num%i==0)
            sum+=i;
        ++i;
    }
    return num==sum; // returns true if sum and num are the same, else returns false;
}

Or perhaps using a for loop:

///////////////////////////////////////////////////////////////
/// Test whether a number is perfect
///////////////////////////////////////////////////////////////
/// \param <num> number to test
/// \return <bool> true=perfect, false=not perfect
///////////////////////////////////////////////////////////////
bool IsPerfect(int num)
{
    int sum=0;
    for(int i=1; i<num; ++i)
        if(num%i==0)
            sum+=i;

    return num==sum; // returns true if sum and num are the same, else returns false;
}

If you look at the above snippets, the code for your perfect number test has been refactored into a function. The variables i and sum, which were global in your original code are now local to the function, so the global definitions can be removed because they simply aren't needed!

If your create a similar function for your prime number test; after the user has entered a number, you can do this in your main function:

if (IsPerfect(num))
{
  // Do whatever you want to do if the number is perfect
}
else
{
  // Do whatever you want to do if the number is not perfect
}

if (IsPrime(num))
{
  // Do what you want to do if the number is prime
}
else
{
  // Do what you want to do if the number is not prime
}

For a function to find all of the factors, a factor is any number which exactly divides another number. So you simply need to loop through from 1..num to find all numbers that divide the user entered number leaving a remainder of 0. In fact, you are already calculating factors in your perfect number code! If a number is a factor of the user entered number, it is added to sum.
For your factor function, you just need to calculate all of the factors for the user entered number and output them!

And when it comes to outputting the factors, you can either display them on the fly (i.e. immediately after a factor has been identified) or you can store them in an array, or a std::vector (if you've been familiarised with the std::vector container in your programming course) and display them after they've all been calculated.

And if you only want to display the prime factors; again, you've already written code to determine if a number is prime or not so you already know how to do that!

So you already have pretty much all the code you need. You just need to organise it a little better!

Once again, move your code for your prime and perfect tests into separate functions and remove all of the global variables because they are not needed. Then add a function to deal with calculating and outputting the factors.

You've already done 80-90% of the work, you just need to do a few things to finish it off! :)

This article has been dead for over six months. Start a new discussion instead.