我有以下程序:

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字符?

接下来,作者提出了两种解决此类问题的方法:
  • 使用fflush()
  • 写一个这样的函数:
    void
    clear (void)
    {
      while ( getchar() != '\n' );
    }
    

  • 该代码实际上起作用了。但是我无法向自己解释它是如何工作的?因为在while语句中,我们使用getchar() != '\n',这意味着读取除'\n'之外的任何单个字符?如果是这样,在输入缓冲区中仍然保留'\n'字符吗?

    最佳答案



    您在第二行看到的行为是正确的,但这并不是正确的解释。使用文本模式流,平台使用什么行尾都无所谓(回车符(0x0D)+换行符(0x0A),裸CR还是LF)。 C运行时库将为您解决这些问题:您的程序将只看到'\n'的换行符。

    如果键入一个字符并按Enter,则该输入字符将在第1行被读取,然后'\n'将在第2行被读取。请参阅comp.lang.c FAQ中的I'm using scanf %c to read a Y/N response, but later input gets skipped.

    至于建议的解决方案,请参阅(同样来自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?

  • 基本上说,唯一可移植的方法是:
    int c;
    while ((c = getchar()) != '\n' && c != EOF) { }
    

    之所以可以使用getchar() != '\n'循环,是因为一旦调用getchar(),返回的字符已从输入流中删除。

    另外,我有义务阻止您完全使用scanf:Why does everyone say not to use scanf ? What should I use instead?

    07-24 09:51
    查看更多