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)
。 试一试,看看它是否适合你。