我有一个类似的测试代码
#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("nnnResult : %cn%sn", c, str);
return 0;
}
我读过一些文章,说这个代码会起作用,因为扫描c字符后,缓冲区中仍然有"\n"字符。fflush(stdin)将清除缓冲区,因此gets()函数可以正常工作
但事实上,当我在Mac OS环境中编译和运行这些代码时,fflush(stdin)什么都不做。我输入了一个字符(例如"k"),然后它打印k字符和一个"\n"字符。它假设允许我输入一个字符,一个字符串,然后打印这两个字符。有人知道为什么吗?谢谢
fflush(3)被记录为处理输出流,而不是处理输入流。
标准没有指定输入流的行为。
特别是针对fflush
的POSIX规范没有提到输入流。因此,从POSIX的角度来看,这可能是一种未定义的行为。
然而,在Linux上fflush(stdin)
是可能的(但我不推荐),因为
对于与相关联的输入流,但不是管道或终端),则
fflush()
丢弃任何缓冲的数据已从基础文件中提取,但尚未使用通过应用程序。对于输入流,fflush()将丢弃任何已从基础文件中提取的缓冲数据,但未被应用程序使用。
(注意提到可查找文件;通常您的stdin
是一个不是真正磁盘文件的终端,lseek(2)会在终端上失败)
BTW,gets(3)被弃用,因为危险(可能的缓冲区溢出!)并且已经从C11标准中消失。至少使用fgets(3),最好使用getline(3)。也许可以考虑GNU readline库(它提供了很好的编辑能力)。
因为fflush(stdin)
就是undefined behavior
。
fflush()
函数仅用于streams open for output
,而非输入。这种方法似乎可以与一些C编译器配合使用,但完全不可移植!因此,不应使用它。