Search code examples
cstdinfgetcfflush

undefined behaviour while using fgetc(stdin)


Before asking this question, I have read: fgetc(stdin) in a loop is producing strange behaviour. I am writing a program to ask the user if they want to exit. Here is my code:

#include<stdio.h>
#include<stdlib.h>

int ask_to_exit()
{
    int choice;
    while(choice!='y'||choice!='n')
    {   printf("Do you want to continue?(y/n):");
        while((fgetc(stdin)) != '\n');
        choice = fgetc(stdin);
        if(choice=='y') return 0;
        else if(choice=='n') return 1;
        else printf("Invalid choice!\n");
    }
}

int main()
{
    int exit = 0;
    while(!exit)
    {
        exit = ask_to_exit();
    }
    return 0;
}

Since fflush(stdin) is undefined behaviour, I did not use it. After following the solution in the other question, I still get the error. Here is a test run of the above program:

$./a.out
Do you want to continue?(y/n):y<pressed enter key>
<pressed enter key>
Invalid choice!
Do you want to continue?(y/n):y<pressed enter key>
<pressed enter key>
Invalid choice!
Do you want to continue?(y/n):n<pressed enter key>
<pressed enter key>
Invalid choice!
Do you want to continue?(y/n):n<pressed enter key>
n<pressed enter key>
<program exits>

Solution

  • You need to get some input before checking the value of choice or it will be uninitialized. And also, you are draining the left-over input before grabbing the first character, you should do it after:

    int ask_to_exit()
    {
        int choice;
    
        do
        {
            printf("Do you want to continue?(y/n):");
            choice = fgetc(stdin);
    
            while (fgetc(stdin) != '\n');
    
            if (choice == 'y') {
                return 0;
            } else if (choice == 'n') {
                return 1;
            } else {
                printf("Invalid choice!\n");
            }
        } while (1);
    }
    

    ouput:

    Do you want to continue?(y/n):g
    Invalid choice!
    Do you want to continue?(y/n):h
    Invalid choice!
    Do you want to continue?(y/n):j
    Invalid choice!
    Do you want to continue?(y/n):k
    Invalid choice!
    Do you want to continue?(y/n):m
    Invalid choice!
    Do you want to continue?(y/n):y
    Do you want to continue?(y/n):y
    Do you want to continue?(y/n):y
    Do you want to continue?(y/n):n
    Press any key to continue . . .