fflush(stdin)无法在cygwin中使用gcc编译,但使用visual studio 2010进行编译

我(重新)学习编程,我从C开始。我的IDE(如果我可以这么说)是Windows7上的cygwin(32Bit)和Visual-Studio 2010。 我一直在编译用gcc(cygwin)和VS2010编译器编写的代码。 我想,我这样做是因为我认为这是一种很好的学习方式。 无论如何,我刚刚了解了fflush(stdin),即刷新stdin缓冲区。 似乎是一个很好的function,因为使用scanf似乎很痛苦。 所以我根据我的教科书中的一个例子编写了下面的代码。 它在cygwin和VS2010中都使用gcc进行编译。 当我运行VS编译的程序时它工作正常(s.below),当我在cygwin中运行gcc编译的程序时,fflush(stdin)不会刷新stdin缓冲区(s.below)。 我已经读过一些关于fflush(stdin)的线程,在某些情况下有一个未定义的行为。 无论这意味着什么,我都是从C for Linux Programming教科书中获取的。 如果fflush(stdin)不是一个有效的方法来摆脱stdin缓冲区中的东西,还有什么其他标准方法?

非常感谢任何答案!

==在Windows下运行的程序:

enter a long integer and a double 23.00 78.99 lint = 23 dt = 0.00 enter a five digits input 78493 u entered 78 and 493 

==程序在Cygwin中运行:

 enter a long integer and a double 23.00 78.99 lint = 23 dt = 0.00 enter a five digits input u entered 78 and 2665720 

== CODE ====

 long lint; double dt; int fp, sp; char fn[50], ln[50]; /* using the l modifier to enter long integers and doubles */ puts ("enter a long integer and a double"); scanf("%ld %lf", &lint, &dt); printf("lint = %d\ndt = %.2f\n", lint, dt); fflush(stdin); /*DOES NOT WORK UNDER CYGWIN!?*/ /* use field width to split input */ puts("\nenter a five digits input"); scanf("%2d %3d", &fp, &sp); printf("u entered %d and %d\n", fp, sp); 

C11在7.21.5.2.2说(强调我的):

如果stream指向输入流或未输入最近操作的更新流,则fflush函数会将该流的任何未写入数据传送到主机环境以写入该文件; 否则,行为未定义。

这意味着您不应该在输入流上调用fflush (除非您为定义行为的非常特定的操作系统和库编写代码)

有一个很好的理由! 你通常会认为fflush(stdin)会刷新你fflush(stdin)那条线,对吧? 那还有更多。 想象一下像这样运行你的程序:

 $ ./program < input_file 

在这种情况下,理论上所有文件都已经存在于stdin的缓冲区中。 因此,刷新缓冲区等于结束输入,这是一个非常无用的操作。 由于这些原因, fflush在输入流上不能有一个非常明智的行为,这就是为什么它们未定义的原因。


如果要忽略当前行,可以使用更好的方法。 一个例子如下:

 void flush_line(FILE *fin) { int c; do { c = fgetc(fin); } while (c != '\n' && c != EOF); } 

这将按字符读取输入字符并停止,直到出现文件结尾,读取错误或行尾。

在标准中,没有为输入流定义fflush()。 在Microsoft的文档中,它是明确定义的。

结果是,虽然您可以将其与具有明确定义的行为的Microsoft C库一起使用,但这种行为是不可移植的。

如果你想使用GCC并且有这个工作,那么你可以使用MinGW / GCC,因为它使用的是Microsoft的C运行时而不是glibc。

你不应该fflush输入流 。 您观察到的差异来自于此操作的行为未定义的事实。

根据我的理解,你正在为Linux编写这个程序,不管你信不信, fflush(stdin)只适用于Windows。 (这至少是我从我的C书中得到的名为C for dummies)。 Linux上fflush(stdin)的替代方法是fpurge(stdin) 。 试一试,看看它是否适合你。