我有以下程序:
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
键(ASCII 代码 13 )和\n
(ASCII 代码10)。因此,在第 2 行中,它将读取 \n
并且不会等待用户输入字符。
好的,我明白了。但我的第一个问题是:为什么第二个 getchar()
(ch2 = getchar();
) 不读取 Enter 键 (13)
,而不是 \n
字符?
接下来,作者提出了两种方法来解决此类问题:
使用
fflush()
编写这样的函数:
void
clear (void)
{
while ( getchar() != '\n' );
}
这段代码确实有效。但我无法解释它是如何工作的。因为在while语句中,我们使用了getchar() != '\n'
,那就意味着读取除了'\n'
之外的任何单个字符?如果是这样,'\n'
字符是否仍保留在输入缓冲区中?
最佳答案
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.
您在第 2 行看到的行为是正确的,但这并不是完全正确的解释。对于文本模式流,平台使用什么换行符(无论是回车符 (0x0D) + 换行符 (0x0A)、裸 CR 还是裸 LF)并不重要。 C 运行时库将为您处理这个问题:您的程序将仅看到 '\n'
换行符。
如果您键入一个字符并按 Enter 键,则该输入字符将在第 1 行读取,然后 '\n'
将在第 2 行读取。请参阅 I'm using scanf %c
to read a Y/N response, but later input gets skipped.来自 comp.lang.c 常见问题解答。
至于建议的解决方案,请参阅(再次来自 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?
关于c - 如何清除 C 中的输入缓冲区?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54764590/