Just started learning C, and it would be great if you could help me with the following:
I just wrote a program that calculates the factorial of a natural number entered by the user. If the number is negative or a character, it should notify the user with the message You have not entered a natural number.
. This message comes from the function check_if_valid_value
.
So far, it displays that message when entering characters, but doesn't seem to work with negative values. I thought casting the variable as long long unsigned
would do the trick, but doesn't seem to be the case. The thing is the scanf()
function returns a 0
so not sure why the program doesn't run the function check_if_valid_value
so that it returns the message:You have not entered a natural number.
I am looking forward to reading any suggestions to improve this piece of code!
#include <stdio.h>
#include <stdlib.h>
void check_if_valid_value(int value_entered)
{
if (value_entered != 1)
{
printf("You have not entered a natural number.\n");
exit(1);
}
}
void do_the_factorial(int p)
{
int i;
unsigned long long int factorial=1;
for (i = 1; i <= p; ++i)
{
factorial=factorial*i;
printf("%llu\n", factorial);
}
}
int main(void)
{
int value_entered, p;
printf("Enter a natural number:");
value_entered=scanf("%llu",&p);
check_if_valid_value(value_entered);
do_the_factorial(p);
return 0;
}
Problems with your code:
successful_conversions
.%u
, not %llu
.You could also start the factorial loop at 2, since multiplying by 1 is mostly useless. So we have:
#include <stdio.h>
#include <stdlib.h>
void check_if_valid_value(int successful_conversions)
{
if (successful_conversions != 1)
{
printf("You have not entered a natural number.\n");
exit(1);
}
}
void do_the_factorial(unsigned int p)
{
unsigned int i;
unsigned long long int factorial=1;
for (i = 2; i <= p; ++i)
{
factorial=factorial*i;
}
printf("%llu\n", factorial);
}
int main(void)
{
int successful_conversions;
unsigned int p;
printf("Enter a natural number:\n");
successful_conversions=scanf("%u",&p);
check_if_valid_value(successful_conversions);
do_the_factorial(p);
return 0;
}
A word of caution: scanning %u
allows the number to have a sign, which can be negative. If you enter -1 then p will be the largest positive unsigned integer, UINT_MAX
. Then do_the_factorial() will enter a very long loop. You should add some check if p is small enough so the factorial of p does not exceed the range of unsigned long long
.
If you want to test the input more stringently, you should learn how to read in a short string and then test whether the string consists entirely of decimal digits. As a starting point, look at fgets()
.