0

So I was asked to write a function int ncr(int n, int r), which basically computes n choose r and returns the value, but, my code also needs to account for error cases if the user enters negative numbers or invalid input like n lesser than r (or) if the user enters floating point numbers

#include <stdio.h>

int ncr(int n, int r)
{
    if (n - r < r)
    {
        r = n - r;
    }
    
    if (r == 0)
    {
        return 1;
    }
    else return ncr(n-1,r) + ncr(n-1,r-1);
}

int main()
{
    int n, r;
    float n1, r1;
    printf("Input :\n");
    printf("n = ");
    scanf("%f", &n1);
    printf("r = ");
    scanf("%f", &r1);
    printf("Output : ");
    
    n = n1;
    r = r1;

    if (n1 - n > 0 || r1 - r > 0)
    {
        printf("Invalid Input, n and r both should be integer numbers");
        return 1;
    }
    
    if (n <= 0 || r < 0)
    {
        printf("Invalid input, n (or) r should be unsigned numbers");
    }
    else if (n < r)
    {
        printf("Invalid input, n should be greater than or equal to r");
    }
    else
    {
        printf("C(n, r) = %d", ncr(n,r));
    }
    
    return 0;
}

This piece of code works completely fine but, the thing I am concerned with is that there must surely be a better way to account for throwing an error message if the user enters floating point numbers. I handled this case by actually reading a float using scanf("%f", &n1) and scanf("%f", &r1) and later checking whether these floats are just integers or not and accordingly thrown the error if these numbers also have digits after the decimal point.

Instead of using these float duplicates like n1 and r1, can we just not solve the issue by using only int n, r directly?

I've tried doing this too where I read the input directly into n and r without using any float duplicates like n1 and r1

    if (scanf("%d", &n) != 1)
    {
        printf("Output : Invalid Input, n and r both should be integer numbers");
        return 1;
    }
    printf("r = ");
    if (scanf("%d", &r) != 1)
    {
        printf("Output : Invalid Input, n and r both should be integer numbers");
        return 1;
    }

But the output is not satisfying

Input :
n = 6.7
r = Output : Invalid Input, n and r both should be integer numbers

It appears that contro-flow is not going into the first if(scanf("%d", &n) != 1) statement but is going into the second one (I can tell this because r = is being printed on-screen)

This all seems insignificant but it would be great if someone tells a better way to throw an error message if the user enters a float instead of an int without actually reading float numbers like I did (i.e., using duplicates)

  • You don't want to do anything with a "console" or a tty (probably less than 1% of terminals are consoles, and it wouldn't surprise me if that number is closer to .0001%). Write your error messages to stderr and let the caller determine to what device that message is written. – William Pursell Dec 03 '21 at 14:49
  • Don't use `scanf`. Use `fgets` to read the line and then use `strtol` to parse it. – William Pursell Dec 03 '21 at 14:53
  • Is this an exercise you're getting graded on, or a personal challenge to yourself, or a practical (production) program, or what? Reading and validating user input using `scanf` is notoriously difficult, and it's not trivial even if you [don't use `scanf`](https://stackoverflow.com/questions/58403537), but it may not matter so much, because few "real" programs use text input like this any more anyway. If you want to, say, learn how to write a good `ncr` function, I'd concentrate on that, and work just hard enough on my input code that I can get valid integers in to test with. – Steve Summit Dec 03 '21 at 15:22
  • Seriously, the fact that you've declared `ncr` as `int ncr(int n, int r)` provides a pretty good guarantee that its inputs are not going to be floating point! – Steve Summit Dec 03 '21 at 15:26
  • @Steve-summit Yeah, this is an assignment on which I will be graded on. Yes, this input formatting using `scanf()` is being difficult to account for all possible cases. Yeah cool, that's what I am thinking about that all this juglary with input formatting is going too far. – Syam Manoj Kumar Paila Dec 03 '21 at 15:37
  • @Steve-summit, And btw are you that Steve Summit who maintains that faqs in c-language? I am going through that now. Thank you. – Syam Manoj Kumar Paila Dec 03 '21 at 15:38
  • @WilliamPursell Thanks, I will look into that – Syam Manoj Kumar Paila Dec 03 '21 at 15:39
  • @SteveSummit Seemed I didn't tag you properly, yes, the function declaration does take only integer inputs, but, the professor wants to see an error message. Anyway, this does not seem too important of a thing to concentrate much on – Syam Manoj Kumar Paila Dec 03 '21 at 15:42

0 Answers0