Buffered and Unbuffered inputs in C

2019-01-14 07:33发布

问题:

Is there any way to figure out whether the input is buffered or unbuffered (Apart from manual pages.)? Cant we figure out by looking at the names of the functions? Also for echoing and nonechoing... For quick reference where to find the list which has the details of Buffered, Unbuffered, echoing and nonechoing inputs?

回答1:

All stdio.h functions for reading from a FILE may exhibit either "buffered" or "unbuffered" behavior, and either "echoing" or "non-echoing" behavior. What controls these things is not which function you use, but settings on the stream and/or its underlying file descriptor.

  • The standard library function setvbuf can be used to enable or disable buffering of input (and output) by the C library. This has no effect on buffering by the operating system. There are three possible modes: "fully buffered" (read or write in substantial chunks); "line buffered" (buffer until a '\n' character is read or written, but not beyond that); and "unbuffered" (all reads and writes go to the OS immediately).

  • The default buffering for new FILE objects (including stdin and friends) is implementation-defined. Unixy C libraries generally default all FILEs to fully buffered, with two exceptions. stderr defaults to unbuffered. For any other FILE, if setvbuf has not been used on it at the time of the first actual read or write, and isatty is true for the underlying file descriptor, then the FILE becomes line-buffered.

  • Some C libraries provide extension functions, e.g. __flbf and friends on Linux and Solaris, for reading back some of the settings controlled by setvbuf. Keep in mind that, as described above, the buffering mode can change upon the first actual read or write, if it hasn't been explicitly set.

If input is from a file, setvbuf is the only knob you have. If input is from some sort of communication channel, there may be other knobs:

  • On POSIX-conformant systems (read "everything except Windows"), a program can request any of several different modes for terminal input. Of these, the most important distinction to make is between "canonical" and "noncanonical". A terminal in canonical mode exhibits both buffering and echoing. (This buffering is separate from the buffering the C library may do if setvbuf has not been used to disable it.) Non-canonical mode allows you to toggle buffering and echoing separately. The low-level POSIX terminal interface is extensive, complicated, and allows you to both read and write all of these settings.

  • If you think you want to put the terminal in a non-canonical mode, before writing a bunch of code against the low-level POSIX API for doing so, you should first consider whether the readline or ncurses library would make your life easier.

  • If you are reading from a pipe, you are at the mercy of whoever is writing to it; you cannot control the size of the chunks you get.

  • If you are reading from a socket, you may be able to exercise some control over the size of the chunks you get by careful use of recvmsg, but there are no guarantees.

  • I don't know how it is on Windows.



回答2:

ISO/IEC 9899-1999 C99 Language Standard

5.1.2.3 Program execution

...

5) The input and output dynamics of interactive devices shall take place as specified in 7.19.3. The intent of these requirements is that unbuffered or line-buffered output appear as soon as possible, to ensure that prompting messages actually appear prior to a program waiting for input. ...

7.19.3 Files

...

3) When a stream is unbuffered, characters are intended to appear from the source or at the destination as soon as possible. Otherwise characters may be accumulated and transmitted to or from the host environment as a block. When a stream is fully buffered, characters are intended to be transmitted to or from the host environment as a block when a buffer is filled. When a stream is line buffered, characters are intended to be transmitted to or from the host environment as a block when a new-line character is encountered. Furthermore, characters are intended to be transmitted as a block to the host environment when a buffer is filled, when input is requested on an unbuffered stream, or when input is requested on a line buffered stream that requires the transmission of characters from the host environment. Support for these characteristics is implementation-defined, and may be affected via the setbuf and setvbuf functions. ...

7) At program startup, three text streams are predefined and need not be opened explicitly — standard input (for reading conventional input), standard output (for writing conventional output), and standard error (for writing diagnostic output). As initially opened, the standard error stream is not fully buffered; the standard input and standard output streams are fully buffered if and only if the stream can be determined not to refer to an interactive device.



回答3:

You can associate a buffer with a file, including stdin, with setvbuf(). You can change the buffering mode to full, line, or none.



标签: c input buffer