0

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?

jay
  • 3,517
  • 5
  • 26
  • 44

3 Answers3

4

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.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • I changed the code like this. scanf("%d ", &limit); But now output is like this: 1. Enter the limit 2. 3(Comment : Entered Limit and press Enter ket) 3. sswew(Comment : I had to enter something here again and press enter again) 4. Enter a string (Comment : Before entering anything program exits) – jay Dec 17 '13 at 11:58
  • 1
    I don't know why this is not working for me. When giving an extra space after `%d` I have to press an extra character and that makes program to terminate. – haccks Dec 17 '13 at 11:58
  • Joachim Could you please check this? I am using Mac OS X 10.8 and CC Compiler. Above solution is not working for me. – jay Dec 17 '13 at 12:03
  • 1
    @jsq Updated my answer with an alternate solution. – Some programmer dude Dec 17 '13 at 12:11
0

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

Martin Perry
  • 9,232
  • 8
  • 46
  • 114
0

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);
haccks
  • 104,019
  • 25
  • 176
  • 264