Strange behaviour of C code(fgets function)

362 views Asked by At

In my C program, fgets is not reading any data. Please see the below code:

#include <stdio.h>
int main()
{
        char string[50];
        int marks,i,n, limit;
        printf("Enter Limit : \n");
        scanf("%d", &limit);
        FILE *fptr; fptr=(fopen("string.txt","w"));
        if(fptr==NULL){
                printf("Error!");
                return 0;
        }
        printf("Enter a string : \n");
        fgets(string, sizeof(string), stdin);
        fwrite(string, 1, sizeof(string), fptr);
        fclose(fptr);
        return 0;
}

After I entering limit, the program shows "Enter a string" and just exits(Before entering any data). If I remove the scanf("%d", &limit); statement it works fine. Also if add a getchar(); statement above fgets it will work fine. Does anyone know the reason behind this issue?

3

There are 3 answers

4
Some programmer dude On BEST ANSWER

It's because of your use of scanf earlier in the code. When you enter the number as input, you press the Enter key to mark the end of the input and that adds a newline in the input buffer. What scanf does is read the number, but leave the newline (enter key) in the input buffer. Then when you call fgets it sees this lone newline and reads it.

A very simple solution to this is to tell scanf to skip trailing whitespace by adding a single space after the format code:

scanf("%d ", &limit);
/*       ^         */
/*       |         */
/* Note space here */

If the above solution doesn't work, then you can read characters until you get a newline:

int c;
while ((c = fgetc(stdin)) != EOF && c != '\n')
    ;

Also, in Mac OSX there is the fpurge function which can be used to clear unread data from an input stream:

fpurge(stdin);

Note: Thefpurge function is not portable.

On Linux and Windows you can use fflush to perform the same thing fpurge does, but note that it's extensions in the libraries for Linux and Windows that allows it. Calling fflush on an input stream is, according to the C specification, undefined behavior. See e.g. the Linux manual page or the Windows reference page.

0
Martin Perry On

If you use sscanf and enter number, you hit "Enter"... number is processed by sscanf, but "Enter" is handled by fgets

0
haccks On

This is because fgets reads the newline character \n left behind by the previous scanf. One possible way to eat up this \n add a getchar after scanf.

    getchar();
    printf("Enter a string : \n");
    fgets(string, sizeof(string), stdin);