fflush(标准输入)不起作用使用GCC编译Cygwin中但使用Visual Studio 2010编译 [英] fflush(stdin) does not work compiled with gcc in cygwin but does compiled with visual studio 2010

查看:413
本文介绍了fflush(标准输入)不起作用使用GCC编译Cygwin中但使用Visual Studio 2010编译的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我(重新)学习编程和我开始与我的C. IDE(如果我可以这样说)是cygwin的(32位)和Visual-Studio 2010中两个上的Windows7。
我总是编译code我与海湾合作委员会(Cygwin的)编写以及与Visual Studio 2010的编译器。我这样做,我想,因为我觉得这是一个学习的好方法。
无论如何,我刚刚了解fflush(标准输入),即刷新标准输入缓冲区。似乎是一个不错的功能,因为别的,用scanf函数似乎是一个痛苦。
所以我写了下面的code基于从我的教科书的例子。它既与Cygwin的海湾合作​​委员会以及与VS2010编译。当我运行VS编译的程序,它工作正常(s.below),当我在Cygwin中的fflush(标准输入)不刷新标准输入缓冲区(s.below)运行GCC编译的程序。
我看了一下fflush某些线程(标准输入),其在某些情况下,不确定的行为。无论这可能意味着,我把它从C为Linux编程教材。如果fflush(标准输入)不是一个有效的手段在标准输入缓冲区摆脱的东西,其他什么标准方法是在那里?

非常感谢任何答案!

== Windows下的程序运行:

 进入一个长整型和双
23.00 78.99
皮棉= 23
DT = 0.00输入一个五位数字输入
78493
ü进入78和493

== Cygwin中的程序运行:

 进入一个长整型和双
23.00 78.99
皮棉= 23
DT = 0.00输入一个五位数字输入
ü进入78和2665720

== code ====

 长绒毛;
双DT;
INT FP,SP;
焦炭FN [50],LN [50];/ *使用l修饰符进入长整数和双打* /
看跌期权(输入一个长整型和双);
scanf函数(%LD%LF,&安培;皮棉,&安培; DT);的printf(棉绒=%d个\\ NDT =%.2f \\ n,皮棉,DT);fflush(标准输入); / *不工作在Cygwin的!?* // *使用字段宽度分裂输入* /看跌期权(\\ n输入一个五位数字输入);
scanf函数(%2D%3D,&安培; FP,&安培; SP);的printf(U进入%D和%d个\\ N,FP,SP);


解决方案

在C11说7.21.5.2.2(重点煤矿):


  

如果输出流或更新流,其中最近的
  操作未输入, fflush 函数使该流的任何未写入的数据
  被传递到要写入到文件的主机环境; ,否则,行为是不确定的。


这意味着,你不应该叫 fflush 上的输入流(除非你正在写code一个非常特定的操作系统和库所在的行为定义)

有一个很好的理由吧!你通常会认为 fflush(标准输入)将刷新你刚才输入的行,对吧?那么有更给它。想象一下,你运行的程序是这样的:

  $ ./program< INPUT_FILE

在这种情况下,所有的文件是理论上已经在标准输入的缓冲器。因此,刷新缓冲区等于结束你输入这是一个相当无用的操作。由于这些原因, fflush 不能对输入流一种非常明智的行为,这就是为什么它是对他们的不明确的。


如果你想忽略当前行,有更好的方法来做到这一点。一个例子是如下:

 无效flush_line(FILE * FIN)
{
    INT℃;
    做
    {
        C =龟etc(翅);
    }而(C ='\\ n'和;!和C = EOF!);
}

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

I am (re-)learning programming and I started with C. My IDE (if I may say so) is cygwin (32Bit) and Visual-Studio 2010 both on Windows7. I am always compiling the code I write with gcc (cygwin) as well as with the VS2010 compiler. I do so, I guess, because I think it is a good way of learning. Anyway I just learned about fflush(stdin), i.e. flushing the stdin buffer. Seems a good functionality because else, using scanf appears to be a pain. So I wrote the code below based on an example from my text book. It compiles both with gcc in cygwin as well as with VS2010. When I run the VS compiled program it works fine (s.below), when I run the gcc compiled program in cygwin the fflush(stdin) does not flush the stdin buffer (s.below). I have read some threads about fflush(stdin) having an undefined behaviour in some cases. Whatever that may mean, I took it from the C for Linux Programming textbook. If fflush(stdin) is not a valid means to get rid of stuff in the stdin buffer, what other standard method is there?

Thanks a lot for any answers!

==Program run under 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

==Program run in 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 at 7.21.5.2.2 says (emphasis mine):

If stream points to an output stream or an update stream in which the most recent operation was not input, the fflush function causes any unwritten data for that stream to be delivered to the host environment to be written to the file; otherwise, the behavior is undefined.

This means that you shouldn't call fflush on an input stream (unless you are writing code for a very specific operating system and library where the behavior is defined)

There is a good reason for it! You would normally think that fflush(stdin) would flush the line you have just entered, right? Well there's more to it. Imagine running your program like this:

$ ./program < input_file

In this case, all the file is theoretically already in the buffer of stdin. Therefore, flushing that buffer equals ending your input which is quite a useless operation. For such reasons, fflush cannot have a very sensible behavior on input streams and that's why it's undefined on them.


If you want to ignore the current line, there are better ways to do it. One example is the following:

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

This reads the input character by character and stops until either end-of-file, read error or end-of-line occurs.

这篇关于fflush(标准输入)不起作用使用GCC编译Cygwin中但使用Visual Studio 2010编译的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆