Search code examples
creturnfactorial

Returning -1 to a user defined function is resulting to termination of program with exit code 0


In this factorial program when entered any non numeric or negative number then the program should ask to renter the value but in the output the program is getting terminated.

Is it because I am returning -1 in display() function? If so then is it compulsory to return a variable (or other function) value to a function if the function is meant to return a value?

#include <stdio.h>

int display();
void fact_fun(int num_fact);

int main() {
    int num = 0;
    char next;

    next = display();

    if (next == -1) { //WHEN ANY CHARACTER OR NEGATIVE NUMBER IS ENTERED IT WILL ASK TO RENTER
        printf("\nOnly positive number is allowed");
        display();
    }

    while (next >= 0) { //WHEN NEGATIVE NUMBER IS ENTERED IT WILL END THE LOOP
        num = next;
        fact_fun(num);
        next = display();
    }
    return 0;
}

int display() {
    char inp[10] = { 0 };
    int input;
    int index = 0;
    printf("\nEnter number to find factorial or press ENTER KEY to exit: ");

    while (((input = getchar()) != EOF) & (index < 10)) {
        if ((input >= '0') && (input <= '9')) {
            inp[index++] = input;
        } else
        if (input == '\n')
            break;
        else
            return -1;
    }
    input = atoi(inp);

    return input;
}

void fact_fun(int num_fact) {
    int fact = 1;
    if (num_fact == 0) {
        printf("\nFactorial of %d is 1", num_fact);
        return;
    } else {
        for (int i = 1; i <= num_fact; i++) {
            fact = fact * i;
        }
        printf("\nFactorial of %d is %d", num_fact, fact);
    }
}

Also when I press ENTER KEY I am getting output as below:

Factorial of %d is 1
Enter number to find factorial or press ENTER KEY to exit:

And when enter \n the program gets terminate. As per my understanding it should treat the Enter key and \n same. If not then what is the difference and how should I check for ENTER KEY value?


Solution

  • User input is line buffered by default. It is much simpler for your purpose to read input one line at a time from the user, parse it to assert input validity and compute the factorial only for valid input.

    Note also that you can simplify the computation as the special case for 0 is redundant with the code for the general case. You should also check for potential arithmetic overflow as the computation may easily exceed the range of type int and produce undefined behavior.

    #include <stdio.h>
    #include <limits.h>
    #include <stdlib.h>
    
    int display();
    void fact_fun(int num_fact);
    
    int main() {
        int num;
        while ((num = display()) >= 0) {
            fact_fun(num);
        }
        return 0;
    }
    
    int display() {
        char buf[256];
        char *p;
        long value;
    
        for (;;) {
            printf("Enter number to find factorial or press ENTER KEY to exit: ");
            if (fgets(buf, sizeof buf, stdin) == NULL || *buf == '\n')
                return -1;
            errno = 0;
            value = strtol(buf, &p, 0);
            if (p == buf) {
                printf("Invalid input: not a number\n");
            } else {
            if (value < 0) {
                printf("Invalid input: negative values not allowed\n");
            } else
            if (errno != 0 || value > INT_MAX) {
                printf("Invalid input: value too large for type int\n");
            } else {
                return (int)value;
            }
        }
    }
    
    void fact_fun(int num_fact) {
        int fact = 1;
        for (int i = 1; i <= num_fact; i++) {
            if (fact > INT_MAX / i) {
                printf("Invalid input: arithmetic overflow\n");
                return;
            }
            fact = fact * i;
        }
        printf("Factorial of %d is %d\n", num_fact, fact);
    }