我有一个像这样的测试代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char c, str[20];
printf("Enter a character : ");
scanf("%c", &c);
printf("Enter a string : ");
fflush(stdin);
gets(str);
printf("\n\n\nResult : %c\n%s\n", c, str);
return 0;
}
我读过一些文章说这段代码会起作用,因为在扫描c字符后,缓冲区中仍然有'\ n'字符。 fflush(stdin)将清除缓冲区,因此gets()函数可以正常工作
但事实上,当我在Mac OS环境中编译并运行此代码时,fflush(stdin)什么都不做。我输入了一个字符(例如,'k'),然后它打印了k字符和'\ n'字符。它假设允许我输入一个字符,一个字符串,然后打印它们。谁知道为什么? 谢谢!
答案 0 :(得分:8)
fflush(3)被记录为处理输出流,而不是输入流。
标准未指定输入流的行为。
特别是POSIX specification for fflush
没有提到输入流。
所以从POSIX的角度来看,它可能是undefined behavior。
然而,在Linux上fflush(stdin)
是可能的(但我不建议这样做),因为
对于与可搜索文件相关联的输入流(例如,磁盘文件, 但不是管道或终端),
fflush()
会丢弃任何缓冲的数据 已从基础文件中获取,但尚未使用 通过申请。对于输入流,fflush()会丢弃任何输入流 已从基础文件中获取的缓冲数据,但具有 没有被应用程序使用。
(注意提到可搜索文件;通常你的stdin
是一个不是正版磁盘文件的终端,而lseek(2)会在终端上失败)< / p>
BTW,gets(3) 已弃用,因为危险(可能buffer overflow!)并且disappeared来自C11标准。至少使用fgets(3),最好使用getline(3)。也许考虑GNU readline库(它提供了很好的编辑能力)。
答案 1 :(得分:4)
因为fflush(stdin)
是undefined behavior
。
fflush()
函数仅用于streams open for output
,而不是输入。这种方法似乎适用于某些C编译器,但完全不可移植!因此,不应该使用它。