Heavily commented code :
#include <stdio.h>
#include <stdlib.h>
#define USAGE "USAGE: ./program [+ve number upto 20]" // define constants & repetitive texts
int main(int argc, char* argv[]) // argc & argv have universal appeal
{
//int fact = 7; // use larger integer
unsigned long int factorial = 1; // 0! = 1
//if(argc>1) // instead check program is run with an argument
if (argc != 2) { // invalid program run
printf ("\n\t%s\n", USAGE);
return 1; // return non-zero to indicate error to caller
}
int number ; //= atoi (argv[1]); // convert string to integer; number is in argv[1]
// @DavidC.Rankin correction
if (sscanf (argv[1], "%d", &number) != 1) { // to make sure we read "a number"
printf ("\n\tERROR: Invalid Number [%s]\n\t%s\n", argv[1], USAGE);
return 3;
}
if (number > 20 || number < 0) { // long int (64 bits) can't store more than 20!
printf ("\n\tERROR: [%d] Out of valid range [0 to 20]\n\t%s\n", number, USAGE);
return 2; // different number for different scenarios
}
for (int i = 2; i <= number; i++) // you can skip 1 as doesn't make a difference
factorial = factorial * i;
printf("\nAnswer:\t %d! = %lu\n", number, factorial); // %lu for unsigned long int
return 0;
}
When you're learning, it always helps if you learn in increments.