Search code examples
cwhile-loopfgetsinput-buffer

While loop skips the first `fgets()` on second iteration


I know questions like this get asked all the time, and I have read several, however, I never use scanf() in my code like all the other ones, so I cannot find a comparable question. I don't know why on the second, third, fourth and so on iterations, the while loop is skipping my first fgets().

Code:

    int main()
{
    char word[40];
    char answer[2];
    while(true) {
        printf("Please enter word: ");
        fgets(word, sizeof(word), stdin);
        printf("Your word is: %s\n", word);
        printf("Would you like to go again?");
        fgets(answer, sizeof(answer), stdin);
        printf("%d\n", strcmp(answer, "F"));
        if (strcmp(answer, "F") == 0) {
            printf("breaking");
            break;
        } else {
            printf("continuing");
            continue;
        }
    }
}

Output:

Please enter word: Hey
Your word is: Hey

Would you like to go again?Y
Please enter word: Your word is: 

Would you like to go again?Y
Please enter word: Your word is: 

Would you like to go again?Y

...etc.

I figure this has something to do with clearing the input buffer, and I have tried several things, but nothing is working. Second day messing around with C, so I don't understand to much of it. (Python was easier lol)


Solution

  • When you enter Y<ENTER>, then you have 2 characters in the input buffer: Y and \n. Since answer is a char[2] and fgets always writes a C-String, the string saved in answer will be "Y".

    The newline character remains in the input buffer, so the next fgets reads the remainder of the input buffer. Because its a newline, fgets reads only the newline, thus word will have the string "\n".

    You can declare the array answer with a larger dimension (at least 3) or use word instead. If you choose the former, then you should do

    char answer[10];
    ...
    if (strcmp(answer, "F\n") == 0)
       ...
    

    edit

    I'd like to add a quote from the fgets man page, this summarizes how fgets work.

    man fgets

    #include <stdio.h>
    char *fgets(char *s, int size, FILE *stream);
    

    DESCRIPTION

    fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer. A terminating null byte ('\0') is stored after the last character in the buffer.