Home > Mobile >  C do while loop repeats 2 times before checking condition
C do while loop repeats 2 times before checking condition

Time:12-16

Why my do/ while loop repeats 2 times before it checks condition?

int main() {

    char quit;
    quit = getchar();
    do {
        printf("Next state: ");
        clock_t start = clock();
        count_values(a, b);
        clock_t end = clock();
        float seconds = (float)(end - start) / CLOCKS_PER_SEC;
        print_state(b);
        printf("\nTime: %f\n", seconds);
        swap(a, b);
        printf("Press enter to print next generation. To quit, enter 'q'.");
        quit = getchar();
    } while(quit != 'q');
    
    return 0;
}

Only after loop has repeated 2 times, getchar() waits for input, why? How to fix it?

CodePudding user response:

You are probably giving the input manually, therefore when you press the Enter key, a newline character is left behind which is then consumed by the second getchar() call.

To bypass this, you can use fgets().

   char quit[100];

   fgets(quit, sizeof(quit), stdin);

    do {
        printf("Next state: ");
        clock_t start = clock();
        clock_t end = clock();
        float seconds = (float)(end - start) / CLOCKS_PER_SEC;
        printf("\nTime: %f\n", seconds);
        printf("Press enter to print next generation. To quit, enter 'q'.");
        fgets(quit, sizeof(quit), stdin);
    } while(quit[0] != 'q');

While the above code should do the job, one can easily trick the program, by typing anything that starts with q.

The solution would be to use strcmp() to check that the string only contains "q".

Note that fgets() also stores the newline character in the buffer, to bypass that you need to replace it with a NULL byte.

   char quit[100];

    do {
        printf("Next state: ");
        clock_t start = clock();
        clock_t end = clock();
        float seconds = (float)(end - start) / CLOCKS_PER_SEC;
        printf("\nTime: %f\n", seconds);
        printf("Press enter to print next generation. To quit, enter 'q'.");
        fgets(quit, sizeof(quit), stdin);
        quit[strcspn(quit, "\n")] = '\0'; /* get rid of \n */
    } while(strcmp(quit, "q") != 0);

CodePudding user response:

It does not repeat twice before checking the condition. You can check that by slightly modifying your code, which also makes it a minimal reproducible example:

#include <stdio.h>

int test(char c) {
    printf("Testing input: %d\n", c);
    return c != 'q';
}

int main() {
    char quit;
    quit = getchar();
    do {
        printf("Press enter to print next generation. To quit, enter 'q'.\n");
        quit = getchar();
    } while(test(quit));

    return 0;
}

You can see that the input is already being tested after the first loop. It is not 'q', if you type q then [enter]. The q will be consumed by the quit = getchar(); before the loop. Then the newline character (decimal 10) will be checked in the condition, and it is not q.

So your assumption was wrong.

  • Related