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

时间:2013-11-19 20:10:01

标签: c visual-studio-2010 cygwin fflush

我(重新)学习编程,我从C开始。我的IDE(如果我可以这么说)是Windows7上的cygwin(32Bit)和Visual-Studio 2010。 我一直在编译用gcc(cygwin)和VS2010编译器编写的代码。我想,我这样做,因为我认为这是一种很好的学习方式。 无论如何,我刚刚了解了fflush(stdin),即刷新stdin缓冲区。似乎是一个很好的功能,因为使用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);

4 个答案:

答案 0 :(得分:2)

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

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

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

答案 1 :(得分:1)

You should not fflush an input stream。您观察到的差异来自于此操作的行为未定义的事实。

答案 2 :(得分:1)

C11在7.21.5.2.2说(强调我的):

  

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

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

这是有充分理由的!您通常会认为fflush(stdin)会刷新您输入的行,对吗?那还有更多。想象一下像这样运行你的程序:

$ ./program < input_file

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


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

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

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

答案 3 :(得分:0)

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