Which Functions in C can we Use to Modify Buffering?

«
»
Question: Which Functions in C can we Use to Modify Buffering?

Answer: As we know streams are mostly fully buffered and have default buffer size. This is defined in ‘stdio.h’ header. Below included code fragment, taken from ‘stdio.h’, indicates default buffer size.

/* Default buffer size.  */
#ifndef BUFSIZ
# define BUFSIZ _IO_BUFSIZ
#endif

Sometimes, there are situations where default buffer is inappropriate. We have functions which allow us to modify buffer provided that stream has already been opened and no operations have been performed on the stream. Let’s see theirs’ prototypes below,

advertisement
    void setbuf(FILE *stream, char *buf);
    int setvbuf(FILE *stream, char *buf, int mode, size_t size);

‘setbuf()’ installs an alternative array for buffering. Array must be BUFSIZ characters long. Assigning your own buffer to a stream prevents I/O library from dynamically allocating a buffer for it. If setbuf() called with NULL argument, it turns off all buffering for the specified stream. Then writing to and/or reading from the stream will be exactly as directed by the program.

Though. we can modify buffer by our own, be very careful that an automatic array shouldn’t be used for buffering. It might be that execution leaves the block in which the array was declared before stream was closed. Then stream will keep on using memory even if it it would have been assigned to some other programs for some other purposes. For ex., just relevant code is written below,

advertisement
int main(void)
{
    FILE *input;
 
    input = fopen("file.txt", "a+");
    /* code to verify whether stream opened successfully */
 
    /* calling read_write() */
    read_write(input);
 
    /* other code */
 
    return 0;
}
 
void read_write(FILE *input)
{
    char buf[BUFSIZ];
 
    /* set appropriate buffer */
    setbuf(input, buf);
 
    /* process read and write from the file */
}

Notice that when execution leaves read_write() function ‘buf’ is no longer existing while ‘input’ stream hasn’t been closed yet and so still using the memory.

The other more general function to modify buffer is ‘setvbuf()’ which is prototyped below,

    int setvbuf(FILE *stream, char *buf, int mode, size_t size);

Notice that mode argument specifies type of buffering for the stream. That is _IOFBF indicated fully buffered stream; _IONBF indicates unbuffered stream and _IOLBF indicated line buffered stream. If output stream is line buffered, it’s always flushed when a newline character is written to the stream. buf and size arguments specify the buffer to use. If buf is NULL, then zero must be given for size. Genrally it’s best to use an array of BUFSIZ characters for a buffer. Most operating systems buffer input/output operations to the disk internally. If buffer size chosen isn’t a multiple of operating system’s buffer size, there might require some extra operations to read or write a fraction of a block. If a large bffer is needed, chose buffer size mutiple of BUFSIZ. The following code fragmnt is taken from ‘stdio.h’ header

advertisement
/* The possibilities for the third argument to `setvbuf'.  */
#define _IOFBF 0                /* Fully buffered.  */
#define _IOLBF 1                /* Line buffered.  */
#define _IONBF 2                /* No buffering.  */

Sanfoundry Global Education & Learning Series – 1000 C Tutorials.

If you wish to look at all C Tutorials, go to C Tutorials.

advertisement
Manish Bhojasia, a technology veteran with 20+ years @ Cisco & Wipro, is Founder and CTO at Sanfoundry. He is Linux Kernel Developer & SAN Architect and is passionate about competency developments in these areas. He lives in Bangalore and delivers focused training sessions to IT professionals in Linux Kernel, Linux Debugging, Linux Device Drivers, Linux Networking, Linux Storage, Advanced C Programming, SAN Storage Technologies, SCSI Internals & Storage Protocols such as iSCSI & Fiber Channel. Stay connected with him @ LinkedIn