{"id":3701,"date":"2019-08-10T00:01:50","date_gmt":"2019-08-10T07:01:50","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=3701"},"modified":"2019-08-03T09:51:36","modified_gmt":"2019-08-03T16:51:36","slug":"extremely-buffered-output","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=3701","title":{"rendered":"Extremely Buffered Output"},"content":{"rendered":"<p>A few weeks back, I wrote a <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=3675\">post on the <em>fflush()<\/em> function<\/a>, which immediately relieves an output buffer, releasing its contents. The mirror opposite of this function might be another output control function, <em>setbuf()<\/em>.<br \/>\n<!--more--><br \/>\nTo understand what <em>setbuf()<\/em> does, as well as <em>fflush()<\/em>, I must blather on about how output buffering works in C.<\/p>\n<p>&lt;blather&gt;<br \/>\nFor text output, C uses three types of buffering: unbuffered, block buffered, and line buffered. You&#8217;ve probably seen this type of buffering in action, but didn&#8217;t recognize what it was or that clever terms existed to describe it.<\/p>\n<p><strong>Unbuffered<\/strong> output is generated as soon as it&#8217;s written. The characters aren&#8217;t stored.<\/p>\n<p><strong>Block buffered<\/strong> output implies that characters are stored in a buffer. When the buffer gets full, its contents are dumped <em>en masse<\/em> to the output device. The buffer is also dumped by an <em>fflush()<\/em> statement or when closing the output device, such as a file.<\/p>\n<p><strong>Line buffered<\/strong> output works like block buffered, though when a newline is encountered, the buffer is output.<\/p>\n<p>In C, file output is block buffered. Output to <em>stdout<\/em> is line buffered. The <em>stderr<\/em> device is unbuffered.<br \/>\n&lt;\/blather&gt;<\/p>\n<p>The <em>setbuf()<\/em> function alters buffering behavior for an output device, <em>stdout<\/em> or an open file handle. Here&#8217;s the format:<\/p>\n<p><code>void setbuf(FILE *restrict stream, char *restrict buf);<\/code><\/p>\n<p>The <code>stream<\/code> argument is a <em>FILE<\/em> handle or <em>stdout<\/em> for the standard output stream. The second argument, <code>buf<\/code>, is a character buffer set to the size <em>BUFSIZ<\/em>. The <em>BUFSIZ<\/em> defined constant is set in the <code>stdio.h<\/code> header. If you want to set a different size, use the <em>setbuffer()<\/em> function instead, where the third argument sets the buffer&#8217;s size.<\/p>\n<p>The following code demonstrates how each line sent to standard output is line-buffered. The <em>getchar()<\/em> function pauses output, then the final line is sent.<\/p>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n\r\nint main()\r\n{\r\n    puts(\"Hold it!\");\r\n    puts(\"Hold it!\");\r\n    puts(\"Go!\");\r\n    getchar();\r\n    puts(\"Thank you.\");\r\n\r\n    return(0);\r\n}<\/pre>\n<p>Here&#8217;s the output:<\/p>\n<p><code>Hold it!<br \/>\nHold it!<br \/>\nGo!<\/code><br \/>\n<em>(Enter is pressed.)<\/em><br \/>\n<code>Thank you.<\/code><\/p>\n<p>In this modification to the code, the <em>setbuf()<\/em> function activates blocked buffering for standard output, holding all text sent to <em>stdout<\/em> until the program stops (or the buffer fills):<\/p>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n\r\nint main()\r\n{\r\n    char buffer[BUFSIZ];\r\n\r\n    <span class=\"comments\">\/* setup the buffer *\/<\/span>\r\n    setbuf(stdout,buffer);\r\n\r\n    puts(\"Hold it!\");\r\n    puts(\"Hold it!\");\r\n    puts(\"Go!\");\r\n    getchar();\r\n    puts(\"Thank you.\");\r\n\r\n    return(0);\r\n}<\/pre>\n<p>The <em>setbuf()<\/em> function at Line 8 redirects output to <em>stdout<\/em> to the <code>buffer<\/code> declared at Line 5. Output waits until the buffer is full, the buffer is flushed, or in this case when the program stops:<\/p>\n<p><em>(Enter is pressed.)<\/em><br \/>\n<code>Hold it!<br \/>\nHold it!<br \/>\nGo!<br \/>\nThank you.<\/code><\/p>\n<p>If you&#8217;re a Unix nerd, I recommend you read the documentation in the man page for <em>setbuf()<\/em>. It&#8217;s interesting to see how file I\/O can be manipulated. Further, you can set an environment variable to control buffering in the terminal window. It&#8217;s pretty cool stuff, nerdy, but good.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>You can direct an output buffer to &#8220;hold it&#8221; until your code finally finds a rest stop. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=3701\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-3701","post","type-post","status-publish","format-standard","hentry","category-main"],"_links":{"self":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/3701","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3701"}],"version-history":[{"count":3,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/3701\/revisions"}],"predecessor-version":[{"id":3706,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/3701\/revisions\/3706"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3701"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3701"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3701"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}