-2

I'm trying to write a code that outputs the below as an extension to a program that output perfect numbers. I'm really struggling with the idea of arguments in C++ and need a little guidance so that the program outputs the correct numbers depending on the argument.

Extend the program so that the badness limit can be specified as a second command line argument. For example, print_perfect_numbers 100 3 should print 2 3 4 6 8 10 16 18 20 28 32 64.

my code so far:

#include <iostream>
#include <cstdlib>

using namespace std;

void print_perfect_numbers(int n, int b) {
    for(int c = 2; c < n; c++) {

        int t = 1;

        for (int f = 2; f * f < c; f++) {
            if (c % f == 0) {
                t += f + c / f;
            }
        }

        if (c == t) {
            cout << c << " ";
        }

        else if ((c >= 2) && (t >= (c - b)) && (t <= (c + b))) {
            cout << c << " ";
        }
    }
}

int main(int argc, char* argv[]) {
    print_perfect_numbers(100,0);
    print_perfect_numbers(100,3);
}

to add more context, the original code calculated the perfect numbers (numbers that have factors that equal the number ie 6 is perfect as its factors add up to it 1 + 2 + 3 = 6) up to 100. Quite Good numbers have a badness of a specified value (for the code im writing it is 3) where the factors of a number can equal the original number + or - the badness.

I can get the output of the numbers, however I'm trying to gain separate outputs as arguments for perfect numbers and quite good numbers up to 100.

my output currently is 6 28 2 3 4 6 8 10 18 20 28 32. i need to make it so the code outputs: 6 28 2 3 4 6 8 10 18 20 28 32 and no, a cout << endl; wont suffice.

pls help :)

Codie
  • 3
  • 3
  • 5
    Does this answer your question? [What does int argc, char \*argv\[\] mean?](https://stackoverflow.com/questions/3024197/what-does-int-argc-char-argv-mean) – Object object Mar 19 '20 at 11:00
  • I can't really understand what should the function do, you should write a better explanation of the problem. – Kerek Mar 19 '20 at 11:53
  • 1
    Show us your code output, Then we can help you better – Mehdi Mostafavi Mar 19 '20 at 12:05
  • edited for more context as well as current output, thanks. – Codie Mar 19 '20 at 12:06
  • more context for output if this helps, testing it against values as arguments ```Failed test 0: differences in output arguments 100 expected stdout 6 28 observed stdout 6 28 2 3 4 6 8 10 18 20 28 32 ``` – Codie Mar 19 '20 at 12:14

1 Answers1

0

All you need to know is that:

  1. argc is the number of command line arguments received by the program, that includes the name of the program for all current OS, meaning, argc >= 1, and you should ignore the first argument in argv.

  2. argv is an array of all the arguments passed in console, as strings (char* and not std::string!)

In order to get the input, you should parse the second and third arguments of argv, if passed. Notice, that you are getting strings and not integers, therefore, you need to parse them into integers, using the following code (assuming the usage is ./program <badness_factor> <upper_bound>:

    uint64_t upper_bound = 100;
    uint64_t badness_factor = 0;

    if (argc > 1)
    {
        badness_factor = std::stoul(argv[1]);
        if (argc > 2)
        {
            upper_bound = std::stoul(argv[2]);
        }    
    }

Also, I have made some changes to your code, making it more readable, because the code currently isn't!

#include <iostream>
#include <cstdlib>
#include <cstdint>
#include <string>

bool is_quite_perfect(uint64_t number, uint64_t badness_factor)
{
    uint64_t divisor_sum = 1;

    for (uint64_t divisor = 2; divisor * divisor < number; ++divisor) 
    {
        if (number % divisor == 0)
        {
            uint64_t corresponding_divisor = number / divisor;
            divisor_sum += divisor + corresponding_divisor;
        }
    }

    return (number == divisor_sum) ||  
            (divisor_sum >= (number - badness_factor)) 
             && (divisor_sum <= (number + badness_factor));
}

void print_quite_perfect_numbers(uint64_t upper_bound, uint64_t badness_factor) 
{
    for(uint64_t num = 2; num < upper_bound; ++num) 
    {
        if (is_quite_perfect(num, badness_factor))
        {
            std::cout << num << " ";
        }        
    }

    std::cout << std::endl;
}

int main(int argc, char* argv[]) 
{
    uint64_t upper_bound = 100;
    uint64_t badness_factor = 0;

    if (argc > 1)
    {
        badness_factor = std::stoul(argv[1]);
        if (argc > 2)
        {
            upper_bound = std::stoul(argv[2]);
        }    
    }

    print_quite_perfect_numbers(upper_bound, badness_factor);
}
Kerek
  • 1,106
  • 1
  • 8
  • 18