如何清除C中的输入缓冲区?

我有以下节目:

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;}

正如上述代码的作者所解释的:程序将不能正常工作,因为在第1行,当用户按Enter键时,它将留在输入缓冲区2字符中:Enter key (ASCII code 13)\n (ASCII code 10)..因此,在第2行,它将读取\n并且不会等待用户输入字符。

好的,我来处理。但我的第一个问题是:为什么第二个getchar() (ch2 = getchar();)不读取Enter key (13),而不是\n角色?

接下来,作者提出了解决这类问题的两种方法:

  1. 使用fflush()

  2. 编写如下函数:

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

这个代码实际上起作用了。但我无法解释它是如何工作的?因为在while语句中,我们使用getchar() != '\n',这意味着读取除'\n'?如果是,则在输入缓冲区中仍然保留'\n'角色?


慕田峪4524236
浏览 660回答 3
3回答

海绵宝宝撒

程序将无法正常工作,因为在第1行,当用户按Enter时,它将留在输入缓冲区2字符中:Enter键(ASCII代码13)和\n(ASCII代码10)。因此,在第2行,它将读取\n,而不会等待用户输入字符。您在第2行看到的行为是正确的,但这不是完全正确的解释。对于文本模式流,不管平台使用什么行尾(无论是回车返回(0x0D)+linefeed(0x0A)、裸CR还是裸LF)。C运行时库将为您处理这个问题:您的程序将只看到'\n'换新线路。如果键入一个字符并按Enter键,则该输入字符将按第1行读取,然后'\n'将由第2行读取。看见我在用scanf %c读取Y/N响应,但稍后将跳过输入。至于拟议的解决办法,见(同样来自于comp.lang.c FAQ):如何才能刷新挂起的输入,这样用户的打字机就不会在下一个提示符中读取?将要fflush(stdin)工作?如果fflush不会工作,我能用什么来冲洗输入?从根本上说,唯一的可移植方法是:int c;while ((c = getchar()) != '\n' && c != EOF) { }你的getchar() != '\n'循环工作,因为一旦您调用getchar(),返回的字符已经从输入流中删除。另外,我觉得有义务劝阻你不要使用scanf完全:为什么每个人都说不要用scanf?我应该用什么代替?

眼眸繁星

你也可以这样做:fseek(stdin,0,SEEK_END);

心有法竹

台词:int ch;while ((ch = getchar()) != '\n' && ch != EOF)     ;不会只读取行提要之前的字符('\n')。它读取流中的所有字符(并丢弃它们)。直至并包括下一个行提要(或者遇到EOF)。要使测试为真,它必须先读取行提要;因此,当循环停止时,linefeed是最后读取的字符,但它已被读取。至于为什么它读取行提要而不是回车,这是因为系统已经将返回转换为linefeed。当按下Enter键时,这意味着线路的结束.但是流包含一个行提要,因为这是系统的正常行尾标记。这可能与平台有关。此外,使用fflush()在输入流上,并不是所有的平台都能工作;例如,它通常不能在Linux上工作。
打开App,查看更多内容
随时随地看视频慕课网APP