0

I have a large program, a text twist game with graphics in c. somewhere in my code i use kbhit() i did this code to clear my input buffer:

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

This code works and wait for me to hit enter key to exit from the loop. The problem is, the loop waits me to hit enter, any other key will output in the screen (unreadable). My question, is there any other way to clear the input buffer without pressing anything, like using fflush to clear output buffer?

Sathish
  • 3,740
  • 1
  • 17
  • 28
paul
  • 372
  • 4
  • 17
  • All we know is that you're using `c` and that your platform has a keyboard and screen. How can we know what capabilities your keyboard has, your keyboard driver has, or anything like that? – David Schwartz Jul 31 '14 at 10:05
  • 1
    http://stackoverflow.com/questions/17263037/kbhit-with-double-loop-not-working-well – BLUEPIXY Jul 31 '14 at 10:25
  • @user3121023 But it still wait for me to press enter key. – paul Jul 31 '14 at 23:48
  • @DavidSchwartz do we really need to know those things? What is the neccessity of knowing keyboard and driver? Please explain. thanks. Btw, im using windows 7, desktop computer. – paul Jul 31 '14 at 23:49
  • @BLUEPIXY I already read that thread before i asked this question. Its very clear that the problem of that thread is using multiple kbhit() and that you need to clear the input buffer everytime you enter another kbhit(). but thanks anyway. – paul Jul 31 '14 at 23:56
  • @user3121023 But it still wait for me to press enter key. – paul Aug 01 '14 at 02:03
  • @PaulJabines For example, if your keyboard driver only supports line mode, then this is impossible. If your terminal has local line editing that can't be disabled, then this is impossible. Your question seems to be be based on the assumption that `C` only works on computers just like the one you're working on. – David Schwartz Aug 01 '14 at 03:33

1 Answers1

1

Assuming you're on some kind of Unix variant....

There are two things you need to clear here:

  1. The FILE * input buffer managed by the C library.
  2. The OS input buffer that your program has not yet read.

The first can be cleared with fflush, just like output streams, except that the data is simply discarded rather than written out.

The second requires some low-level OS I/O calls. In general you should not mix these with the FILE * I/O functions, but they should be safe between fflush and any other read/get operation.

First, you'll need to use select to see if a read operation would block. This effectively checks to see if the OS buffer is clear. If the read would not block, then you do a one-character read, and repeat the select. The key point is that you have to check if there is data to read before you read and discard it, or else it will block until there is data to read.

The code might look something like this (untested):

fflush(stdin);
int stdinin_fd = fileno(stdin);

while (1) {
    fdset readset;
    FD_ZERO(&readset);
    FD_SET(stdin_fd, &readset);
    struct timeval timeout = {0, 0};

    int result = select(stdin_fd+1, &readset, NULL, NULL, timeout);
    if (result == 1) {
        char c;
        read(stdin_fd, &c, 1);
    } else if (result == 0
               || (result == -1 && errno != EINTR)) {
        break;
    } // else loop
}

It might be possible use a larger read-size when clearing the OS buffers, which would be more efficient, but I'm not sure about the portability of that, and anyway I'm assuming there won't be much data to clear.

ams
  • 24,923
  • 4
  • 54
  • 75
  • calling `tcflush(stdin_fd, TCIFLUSH)` should be all that is needed to flush the OS level input buffer on any POSIX system... – Chris Dodd Jul 31 '14 at 16:45
  • @ChrisDodd interesting. That one is new to me, obviously. You should post that as an answer. – ams Jul 31 '14 at 21:26
  • Im on windows 7. :( I bet this is not applicable to windows user. – paul Jul 31 '14 at 23:51
  • 1
    Of you're using the POSIX compatibility functions then it *might* work, but i wouldn't bet on it. It's usually helpful to post details like that in the question. – ams Aug 01 '14 at 07:42