1

I am getting an error at while loop it says

error: '&&' within '||' [-Werror,-Wlogical-op-parentheses]
       while((credit % 10 >= 0) && (i < 15) || (i < 16))

here is my code for the credit also please check if my logic is correct.

#include<cs50.h>
#include<stdio.h>

int main(void)
{
    int count=0;
    long int credit;
    int sum = 0;
    int sum1 = 0;
    int i=0;
    int t,s;
    do
    {
        credit = get_long("Number: ");
    }
    while(credit < 1);

    while((credit%10) > 0)
    {
        count++;
    }

    if((count != 15) || (count != 16))
    {
        printf("INVALID\n");
        return 0;
    }
    else
    {
       while((credit % 10 >= 0) && (i < 15) || (i < 16))
       {
           i++;
           if(i%2 != 0)
           {
               sum = sum + (credit % 10);
           }
           else
           {
               t = 2 * (credit % 10);
               while(t%10 >= 0){
                   sum1 = sum1 + (t%10);
               }
           }
       }
        s = sum + sum1;
        if (s%10 == 0)
        {
            printf("valid credit\n");
        }
        else
        {
            printf("invalid credit\n");
        }
    }
}
2

The compiler is actually giving a warning, but the compiler flags are set up to treat all warnings as errors. It's still best to eliminate all warnings.

Here's the reason. For clarity, let's simplify the expression to the essential parts.

   while((a) && (b) || (c))

The compiler isn't sure about how these logical operators should be combined. This expression could mean (a && b) || c or it could mean a && (b || c) It's saying that the expression is ambiguous. You could apply parentheses, as in one of the two examples, to resolve this.

However, let's look at the actual statement,

   while((credit % 10 >= 0) && (i < 15) || (i < 16))

If the form is a && (b || c), then the tests can be simplified. If i < 15 is true, then i < 16 must be true, so i < 15 is redundant. If the form is (a && b) || c, then its absolutely critical that parentheses be added to make it unambiguous. These reasons are probably why the compiler gave a warning.

If this answers your question, please click on the check mark to accept. Let's keep up on forum maintenance. ;-)

3
  • I corrected while loop to while((((credit % 10) > 0) && (i < 15)) || (i < 16)) and it compiled fine the rest of program is same but not giving any output when i enter the credit number not sure which part is logically wrong. this what happens in terminal window. $ make credit clang -fsanitize=signed-integer-overflow -fsanitize=undefined -ggdb3 -O0 -std=c11 -Wall -Werror -Wextra -Wno-sign-compare -Wno-unused-parameter -Wno-unused-variable -Wshadow credit.c -lcrypt -lcs50 -lm -o credit $ ./credit Number: 234234 ^C $ ./credit Number: 4003600000000014 Apr 20 '19 at 5:33
  • To the compiler, a && b || c is about as ambiguous as a * b + c, the && has precedence over ||, like * has precedence over +. Just because humans tend to forget about that, there is a warning if you don't use parentheses to make your intention more explicit.
    – Blauelf
    Apr 21 '19 at 6:17
  • As the loops make not much sense (condition based on the last digit, and not progressing to a next digit within the loop), I couldn't even guess which grouping would be the correct one.
    – Blauelf
    Apr 21 '19 at 6:23
0

You should add brackets, so it'll look like this:

while ((credit % 10 >= 0) && ((i < 15) || (i < 16)))

or this:

while (((credit % 10 >= 0) && (i < 15)) || (i < 16))

(It should actually look like the first one, because 1) I did this pset before, and 2) I read your code

You should also use style50. (No offence) The code is rather messy.

With style50, your code will like what it is here

2
  • i am getting this output when i execute it after correcting it. $ ./credit Number: 4000300020001000 INVALID $ i have also corrected while loop to while ((credit % 10 >= 0) && ((i < 15) || (i < 16))). Apr 21 '19 at 6:29
  • @Rakshith Sridharan First of all, if the number is valid, the program should determine the type of number (AMEX, MASTERCARD, or VISA) the card is. Second, I don't understand what the ``` while ((credit % 10) > 0) { count++; } ``` is for. I used the CS50 IDE to debug it, and the problem is there. You might as well replace it with a for loop to check the amount of digits the card has (I'm assuming that that is the function of the while loop). Apr 22 '19 at 2:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .