Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to clear input buffer in C?

Tags:

c

buffer

I have the following program:

int main(int argc, char *argv[]) {   char ch1, ch2;   printf("Input the first character:"); // Line 1   scanf("%c", &ch1);    printf("Input the second character:"); // Line 2   ch2 = getchar();    printf("ch1=%c, ASCII code = %d\n", ch1, ch1);   printf("ch2=%c, ASCII code = %d\n", ch2, ch2);    system("PAUSE");     return 0; } 

As the author of the above code have explained: The program will not work properly because at Line 1, when the user presses Enter, it will leave in the input buffer 2 character: Enter key (ASCII code 13) and \n (ASCII code 10). Therefore, at Line 2, it will read the \n and will not wait for the user to enter a character.

OK, I got this. But my first question is: Why the second getchar() (ch2 = getchar();) does not read the Enter key (13), rather than \n character?

Next, the author proposed 2 ways to solve such probrems:

  1. use fflush()

  2. write a function like this:

    void clear (void) {       while ( getchar() != '\n' ); } 

This code worked actually. But I cannot explain myself how it works? Because in the while statement, we use getchar() != '\n', that means read any single character except '\n'? if so, in the input buffer still remains the '\n' character?

like image 551
ipkiss Avatar asked Oct 26 '11 02:10

ipkiss


People also ask

How do I clear Scanf input?

'\n'); ” : Typing “while ((getchar()) != '\n');” reads the buffer characters till the end and discards them(including newline) and using it after the “scanf()” statement clears the input buffer and allows the input in the desired container.

What is a buffer in C?

C language's use of a buffer C uses a buffer to output or input variables. The buffer stores the variable that is supposed to be taken in (input) or sent out (output) of the program. A buffer needs to be cleared before the next input is taken in.

What is input buffer?

When referring to computer memory, the input buffer is a location that holds all incoming information before it continues to the CPU for processing. Input buffer can be also used to describe other hardware or software buffers used to store information before it is processed.

What does flushing a buffer mean?

A buffer flush is the transfer of computer data from a temporary storage area to the computer's permanent memory. For instance, if we make any changes in a file, the changes we see on one computer screen are stored temporarily in a buffer.


1 Answers

The program will not work properly because at Line 1, when the user presses Enter, it will leave in the input buffer 2 character: Enter key (ASCII code 13) and \n (ASCII code 10). Therefore, at Line 2, it will read the \n and will not wait for the user to enter a character.

The behavior you see at line 2 is correct, but that's not quite the correct explanation. With text-mode streams, it doesn't matter what line-endings your platform uses (whether carriage return (0x0D) + linefeed (0x0A), a bare CR, or a bare LF). The C runtime library will take care of that for you: your program will see just '\n' for newlines.

If you typed a character and pressed enter, then that input character would be read by line 1, and then '\n' would be read by line 2. See I'm using scanf %c to read a Y/N response, but later input gets skipped. from the comp.lang.c FAQ.

As for the proposed solutions, see (again from the comp.lang.c FAQ):

  • How can I flush pending input so that a user's typeahead isn't read at the next prompt? Will fflush(stdin) work?
  • If fflush won't work, what can I use to flush input?

which basically state that the only portable approach is to do:

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

Your getchar() != '\n' loop works because once you call getchar(), the returned character already has been removed from the input stream.

Also, I feel obligated to discourage you from using scanf entirely: Why does everyone say not to use scanf? What should I use instead?

like image 53
jamesdlin Avatar answered Oct 06 '22 09:10

jamesdlin