Search code examples
cdo-while

Two conditions for DO WHILE loop in C


Could you please explain me why this condition works with || and does not with &&.

I fixed this on my own. I just do not understand why this is OR and not AND.

This program must quit the loop when user inputs Q0.

#include <stdio.h>

int main() {
    
    char character;
    int integer;
    
    printf("Loop started\n\n");
    
    do {
        printf("Enter Q0 to quit the loop: ");
        scanf(" %c%d", &character, &integer);
        
        if (character != 'Q' || integer != 0) {
            printf("Invalid value(s)!\n\n");
        }
        else {
            printf("Correct value(s)!\n");
        }

    } while (character != 'Q' || integer != 0);
   
    printf("\nLoop ended\n");
   
    return 0;
}

Code link


Solution

  • The code is correct and the loop will be exited if and only if the user enters a Q followed by a integer with a value of 0. The test (character != 'Q' || integer != 0) is equivalent to !(character == 'Q' && integer == 0). In plain English, the latter is a more direct translation of continue unless the user typed a Q and the number 0.

    Note however these remarks:

    • using a do / while loop makes you repeat the test inside the loop at as the exit condition. It would be simpler to user a for (;;) loop, aka for ever loop, and use a break statement to exit the loop explicitly when the user types the appropriate sequence, using a positive test.

    • you do not check the scanf() return value, which must be 2 for proper operation. If the user types a sequence that cannot be parsed with " %c%d", the behavior may be incorrect and possibly undefined. For example an input of 10QA will be misinterpreted as a correct value. It is much more reliable to read the input as a string with fgets(), parse it with sscanf and check the return values.

    • %d will convert sequences such as 00, +0 and -0 as the number 0 which may or may not be expected. If the input sequence must match Q0 exactly, the test must be performed some other way.

    Here is a modified version:

    #include <stdio.h>
    
    int main() {
        
        printf("Loop started\n\n");
        
        for (;;) {
            char buf[128];
            char character, c2;
            int integer;
    
            printf("Enter Q0 to quit the loop: ");
            if (!fgets(buf, sizeof buf, sizeof buf)) {
                printf("Unexpected end of file!\n\n");
                break;
            }
            if (sscanf(" %c%d %c", &character, &integer, &c2) != 2) {
                printf("Invalid format: must have a character and an integer!\n\n");
                continue;
            }
            if (character == 'Q' && integer == 0) {
                printf("Correct values!\n");
                break;
            }
            printf("Invalid values: %c%d!\n\n", character, integer);
            printf("Try again.\n");
        }
       
        printf("\nLoop ended\n");
       
        return 0;
    }