2

Currently the first thing I do before I print anything in my program is run setbuf(stdout, _IOFBF);

However printf("hello\n"); will still flush the buffer.

This is bad, I want to control when it sends all its text (In the interest of creating a "smooth" animated gif experience with ascii text in the terminal).

How can I tell my program I would like stdout to be fully buffered?

4
  • 2
    You can buffer it yourself: build a 2D array which represents the entire new "frame" and output it all at once. If you can position the cursor to top left first, it will be quicker because the console does not have to scroll. Commented Mar 17, 2019 at 19:41
  • How can I position the cursor at the top left from the program?
    – jkalsdfjk
    Commented Mar 17, 2019 at 19:50
  • 1
    I believe ncurses is a popular library to use. In Windows, I use SetConsoleCursorPosition(). Commented Mar 17, 2019 at 19:52
  • @jkalsdfjk: you can accept one of the answers by clicking on the grey checkmark below its score
    – chqrlie
    Commented Mar 23, 2019 at 12:52

2 Answers 2

4

You cannot use setbuf this way: setbuf(stdout, _IOFBF);. The second argument is a pointer to an array of BUFSIZ bytes.

You should instead use setvbuf() with a potentially larger buffer size before you perform any output:

setvbuf(stdout, NULL, _IOFBF, 4096);

You can pass an actual array instead of NULL but it is not necessary as setvbuf will allocate the buffer if you don't and might still do that if you do. You may want to check the return value to ensure the call succeeded. If for some unexpected reason this call fails on your system, the output would not be fully buffered.

Here is the C Standard definition:

7.21.5.6 The setvbuf function

Synopsis

    #include <stdio.h>
    int setvbuf(FILE * restrict stream,
                char * restrict buf, int mode, size_t size);

The setvbuf function may be used only after the stream pointed to by stream has been associated with an open file and before any other operation (other than an unsuccessful call to setvbuf) is performed on the stream. The argument mode determines how stream will be buffered, as follows: _IOFBF causes input/output to be fully buffered; _IOLBF causes input/output to be line buffered; _IONBF causes input/output to be unbuffered. If buf is not a null pointer, the array it points to may be used instead of a buffer allocated by the setvbuf function and the argument size specifies the size of the array; otherwise, size may determine the size of a buffer allocated by the setvbuf function. The contents of the array at any time are indeterminate.

Returns

The setvbuf function returns zero on success, or nonzero if an invalid value is given for mode or if the request cannot be honored.

0

You need to use setvbuf to set the buffer mode, size, and location:

buffer = malloc(1024);
setvbuf(stdout, buffer, _IOFBF, 1024);

You need to ensure your buffer is large enough that it will never flush due to capacity if you want total control over flushing.

0

Not the answer you're looking for? Browse other questions tagged or ask your own question.