2

When I run the following code:

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


int main()
{
    int n;
    char y;

    printf("Message\n");
    fscanf(stdin, "%c", &y);

    printf("Message\n");
    fscanf(stdin, "%c", &y);

    return 0;
}

I get this:

Message
{enter character}
Message

The problem is that I am not asked to enter a character twice even if there are 2 scanf functions. The output should be this:

Message
{enter character}
Message
{enter character}



I have this issue for getc() too:

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


int main()
{
    int n;
    char y;

    printf("Message\n");
    y=getc(stdin);

    printf("Message\n");
    y=getc(stdin);

    return 0;
}

Also, fflush() does not help:

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


int main()
{
    int n;
    char y;

    printf("Message\n");
    y=getc(stdin);

    fflush(stdin);
    fflush(stdout);

    printf("Message\n");
    y=getc(stdin);

    return 0;
}

I've tried to fflush stdin, stdout, stdin+stdout (at the same time), but the result is still the same.

Josh Crozier
  • 233,099
  • 56
  • 391
  • 304
webpersistence
  • 894
  • 3
  • 12
  • 29
  • See the various man pages for fflush() - some seem to say it will only work on seekable input streams and explicitly give the terminal as a counterexample. fpurge() might be more along the lines of what you were thinking of. – Chris Stratton Mar 28 '15 at 12:35
  • Where is fpurge() defined? – webpersistence Mar 28 '15 at 12:38
  • `fpurge(stdin);` I get `undefined reference to 'fpurge'` even if I used `#include ` – webpersistence Mar 28 '15 at 12:41
  • 1
    Sorry, my mistake - it turns out that the mere presence of a man page on Linux isn't enough, when it includes this note: "The function fpurge() was introduced in 4.4BSD and is not available under Linux. The function __fpurge() was introduced in Solaris, and is present in glibc 2.1.95 and later." So **you should be able to use __fpurge()** on Linux or fpurge() on OSX (and likely the BSD's). For portability you might just want one of the read-to-exhaustion loops proposed below. – Chris Stratton Mar 28 '15 at 12:48
  • `__fpurge(stdin);` works! – webpersistence Mar 28 '15 at 12:51

3 Answers3

5

Change

fscanf(stdin, "%c", &y);

to

fscanf(stdin, " %c", &y);

Quoting the C11 standard:

7.21.6.2 The fscanf function

[...]

  1. A directive composed of white-space character(s) is executed by reading input up to the first non-white-space character (which remains unread), or until no more characters can be read. The directive never fails.

So, the space before %c discards the \n character left over by the first fscanf. Where did this character come from? Recall that you press enter key after you enter a character. This character is not consumed by the first fscanf and stays in the standard input buffer(stdin).

This also happens in the second version of the program,i.e, the second getc gets the newline character left over by the first one. You can use the following code to flush(clear) the stdin:

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

As for why fflush(stdin); dosen't work is that the standard says that the behavior is undefined:

7.21.5.2 The fflush function

[...]

  1. If stream points to an output stream or an update stream in which the most recent operation was not input, the fflush function causes any unwritten data for that stream to be delivered to the host environment to be written to the file; otherwise, the behavior is undefined.

But note that fflush(stdin) does work in some implementations. Also read this

Community
  • 1
  • 1
Spikatrix
  • 20,225
  • 7
  • 37
  • 83
2

Try this:

printf("Message\n");
fscanf(stdin, "%c", &y);

printf("Message\n");
fgetc(stdin); // you need this to consume the \n entered before
fscanf(stdin, "%c", &y);
Pablo Santa Cruz
  • 176,835
  • 32
  • 241
  • 292
2

Reason for this behavior is the \n character left behind in the input buffer after first input. When you press Enter, then \n goes to the buffer along with the input character. You need to remove that \n. Try this

fscanf(stdin, " %c", &y);  

A space before %c can skip any number of white spaces.

An alternative way to flush the input buffer

int ch;
while((ch=getchar())! = '\n' && c! = EOF);
haccks
  • 104,019
  • 25
  • 176
  • 264