Fflush stdin c что это

от admin

std::fflush

Для выходных потоков (и для потоков обновления, для которых была выведена последняя операция), записывает любые неписанные данные из буфера stream в соответствующее устройство вывода.

Для потоков ввода (и для потоков обновления,для которых была введена последняя операция)поведение не определено.

Если stream является нулевым указателем, все открытые выходные потоки сбрасываются, включая те, которые манипулируются в пакетах библиотеки или иным образом не доступны напрямую программе.

Parameters

stream поток файлов для записи

Return value

Возвращает ноль в случае успеха. В противном случае возвращается EOF и устанавливается индикатор ошибки потока файлов.

Notes

POSIX расширяет спецификацию fflush , определяя его влияние на входной поток, если этот поток представляет файл или другое устройство для поиска: в этом случае указатель файла POSIX перемещается, чтобы соответствовать указателю потока C (что эффективно отменяет любую буферизацию чтения ) и эффекты любых std::ungetc или std::ungetwc , которые еще не были прочитаны из потока, отбрасываются.

Microsoft также расширяет спецификацию fflush, определяя ее влияние на поток ввода: в Visual Studio 2013 и более ранних версиях он отбрасывал входной буфер , в Visual Studio 2015 и новее он не действует, буферы сохраняются .

Fflush stdin c что это

What is a buffer?

A temporary storage area is called a buffer. All standard input and output devices contain an input and output buffer. In standard C/C++, streams are buffered. For example, in the case of standard input, when we press the key on the keyboard, it isn’t sent to your program, instead of that, it is sent to the buffer by the operating system, till the time is allotted to that program.

How does it affect Programming?

On various occasions, you may need to clear the unwanted buffer so as to get the next input in the desired container and not in the buffer of the previous variable. For example, in the case of C after encountering “scanf()”, if we need to input a character array or character, and in the case of C++, after encountering the “cin” statement, we require to input a character array or a string, we require to clear the input buffer or else the desired input is occupied by a buffer of the previous variable, not by the desired container. On pressing “Enter” (carriage return) on the output screen after the first input, as the buffer of the previous variable was the space for a new container(as we didn’t clear it), the program skips the following input of the container.

In the case of C Programming

What does fflush(stdin) do in C programing? [duplicate]

I am very new to C programming and I am trying to understand how fflush(stdin) really works.

In the following example does fflush(stdin) clears all the buffer or it clears whatever entered after the third item? What I mean is user enters account number, space, name, space, balance. Is that true that from this point on, whatever the user enters will be flushed with fflush(stdin) ? and stdin won’t be empty.

Why do I say that is because it enters into a while loop and starts writing to the text file.

My second question is whether Ctrl-Z will tell the OS to stop asking the user for entering input?

2 Answers 2

The answer to this is that fflush(stream) is only formally defined for output streams, so fflush(stdout) is OK, but fflush(stdin) is not.

The purpose of fflush(stream) is to make the operating system flush any buffers to the underlying file. For an example of a legitimate use, students often have problems like “my prompt doesn’t appear!” if they do something like:

However, they find that this works just fine:

Of course, they don’t want a newline after their prompt, so they have a bit of a problem.

The reason for this is that the output to stdout is buffered by the OS and the default behavior is (often) only to actually write the output to the terminal when a newline is encountered. Adding an fflush(stdout) after the printf() solves the problem:

Now, working by analogy, people often think that fflush(stdin) should discard any unused input, but if you think about it a little bit that doesn’t make much sense. What does it mean to “flush” an input buffer? Where is it “flushed” to? If you flush an output buffer, the output is sent to the underlying file or the terminal, where it would eventually wind up anyway, but where would input “eventually end up anyway”? There’s no way of knowing! What should the behavior be if the input stream data comes from a file or a pipe or a socket? It isn’t at all clear for input streams what the behavior of fflush() should be, but it’s very clear for output streams in all cases. Hence, fflush() is only defined for output streams.

The reason why the erroneous use of fflush(stdin) became commonplace is that, many years ago, a few operating systems did implement a scheme where it worked as many people expected, discarding unused input. Microsoft DOS is a good example. Surprisingly, modern versions of Linux also implement fflush() for input streams.

The right thing to do with “extra” unwanted terminal input is simply to read it and do nothing with it. This is almost as easy as calling fflush(stdin) , works everywhere, and doesn’t rely on formally undefined behavior.

The C standard says:

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.

POSIX says (also explicitly defers to C standard):

If stream points to an output stream or an update stream in which the most recent operation was not input, fflush() shall cause any unwritten data for that stream to be written to the file, .

For output streams, fflush() forces a write of all user-space buffered data for the given output or update stream via the stream’s underlying write function. For input streams, fflush() discards any buffered data that has been fetched from the underlying file, but has not been consumed by the application. The open status of the stream is unaffected.

Using fflush(stdin)

Simple: this is undefined behavior, since fflush is meant to be called on an output stream. This is an excerpt from the C standard:

int fflush(FILE *ostream);

ostream 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.

So it’s not a question of «how bad» this is. fflush(stdin) is plainly wrong, and you mustn’t use it, ever.

Читать:
Несовместимое оборудование windows 7 как убрать

Converting comments into an answer — and extending them since the issue reappears periodically.

Standard C and POSIX leave fflush(stdin) as undefined behaviour

The POSIX, C and C++ standards for fflush() explicitly state that the behaviour is undefined, but none of them prevent a system from defining it.

ISO/IEC 9899:2011 — the C11 Standard — says:

§7.21.5.2 The fflush function

¶2 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.

POSIX mostly defers to the C standard but it does mark this text as a C extension.

[CX] For a stream open for reading, if the file is not already at EOF, and the file is one capable of seeking, the file offset of the underlying open file description shall be set to the file position of the stream, and any characters pushed back onto the stream by ungetc() or ungetwc() that have not subsequently been read from the stream shall be discarded (without further changing the file offset).

Note that terminals are not capable of seeking; neither are pipes or sockets.

Microsoft defines the behaviour of fflush(stdin)

Microsoft and the Visual Studio runtime defines the define the behaviour of fflush() on an input stream.

If the stream is open for input, fflush clears the contents of the buffer.

Cygwin is an example of a fairly common platform on which fflush(stdin) does not clear the input.

This is why this answer version of my comment notes ‘Microsoft and the Visual Studio runtime’ — if you use a non-Microsoft C runtime library, the behaviour you see depends on that library.

Linux documentation and practice seem to contradict each other

Surprisingly, Linux nominally documents the behaviour of fflush(stdin) too, and even defines it the same way (miracle of miracles).

For input streams, fflush() discards any buffered data that has been fetched from the underlying file, but has not been consumed by the application.

I remain a bit puzzled and surprised at the Linux documentation saying that fflush(stdin) will work. Despite that suggestion, it most usually does not work on Linux. I just checked the documentation on Ubuntu 14.04 LTS; it says what is quoted above, but empirically, it does not work — at least when the input stream is a non-seekable device such as a terminal.

demo-fflush.c

Example output

This output was obtained on both Ubuntu 14.04 LTS and Mac OS X 10.11.2. To my understanding, it contradicts what the Linux manual says. If the fflush(stdin) operation worked, I would have to type a new line of text to get information for the second getchar() to read.

Given what the POSIX standard says, maybe a better demonstration is needed, and the Linux documentation should be clarified.

demo-fflush2.c

Example output

Note that /etc/passwd is a seekable file. On Ubuntu, the first line looks like:

On Mac OS X, the first 4 lines look like:

In other words, there is commentary at the top of the Mac OS X /etc/passwd file. The non-comment lines conform to the normal layout, so the root entry is:

Ubuntu 14.04 LTS:

The Mac OS X behaviour ignores (or at least seems to ignore) the fflush(stdin) (thus not following POSIX on this issue). The Linux behaviour corresponds to the documented POSIX behaviour, but the POSIX specification is far more careful in what it says — it specifies a file capable of seeking, but terminals, of course, do not support seeking. It is also much less useful than the Microsoft specification.

Summary

Microsoft documents the behaviour of fflush(stdin) . Apparently, it works as documented on the Windows platform, using the native Windows compiler and C runtime support libraries.

Despite documentation to the contrary, it does not work on Linux when the standard input is a terminal, but it seems to follow the POSIX specification which is far more carefully worded. According to the C standard, the behaviour of fflush(stdin) is undefined. POSIX adds the qualifier ‘unless the input file is seekable’, which a terminal is not. The behaviour is not the same as Microsoft’s.

Consequently, portable code does not use fflush(stdin) . Code that is tied to Microsoft’s platform may use it and it will work, but beware the portability issues.

POSIX way to discard unread terminal input from a file descriptor

The POSIX standard way to discard unread information from a terminal file descriptor (as opposed to a file stream like stdin ) is illustrated at How can I flush unread data from a tty input queue on a Unix system. However, that is operating below the standard I/O library level.

According to the standard, fflush can only be used with output buffers, and obviously stdin isn’t one. However, some standard C libraries provide the use of fflush(stdin) as an extension. In that case you can use it, but it will affect portability, so you will no longer be able to use any standards-compliant standard C library on earth and expect the same results.

Похожие статьи