{"id":2871,"date":"2017-12-23T00:01:44","date_gmt":"2017-12-23T08:01:44","guid":{"rendered":"http:\/\/c-for-dummies.com\/blog\/?p=2871"},"modified":"2017-12-16T09:40:54","modified_gmt":"2017-12-16T17:40:54","slug":"safe-coding-practices-putchar-as-a-loop-condition","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=2871","title":{"rendered":"Safe Coding Practices &#8211; <em>putchar()<\/em> as a Loop Condition"},"content":{"rendered":"<p>It&#8217;s not unsafe to use <em>putchar()<\/em> as condition inside a <em>while<\/em> loop. If you dare try it, however, you must ensure that it checks for file errors. That&#8217;s an area where my own code often falls short.<br \/>\n<!--more--><br \/>\nFrom <a href=\"http:\/\/c-for-dummies.com\/blog\/?p=2804\">last week&#8217;s Lesson<\/a>, I demonstrated various <a href=\"http:\/\/c-for-dummies.com\/blog\/?p=2797\">safe coding practices<\/a> for the <em>getchar()<\/em> and <em>putchar()<\/em> functions, most of which deal with the <em>int<\/em> value returned from each function.<\/p>\n<p>Here is what I&#8217;m often guilty of doing in a <em>while<\/em> loop (though this condition could also wiggle into a <em>for<\/em> loop as well):<\/p>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n\r\nint main()\r\n{\r\n    char hello[] = \"Greetings, Human!\\n\";\r\n    char *s;\r\n\r\n    s = hello;\r\n    while(putchar(*s++))\r\n        ;\r\n\r\n    return(0);\r\n}<\/pre>\n<p>Pointer <code>s<\/code> references the string <code>hello<\/code>, which is output one character at a time as the <em>while<\/em> loop&#8217;s condition.<\/p>\n<p>Most often I use the statement <code>while(putchar(*s++));<\/code> as a demonstration of how C can be scrunched up or obfuscated. It&#8217;s a common example. The code expands to something more readable:<\/p>\n<pre class=\"screen\">\r\n    s = hello;\r\n    while( *s != '\\0' )\r\n    {\r\n        putchar(*s);\r\n        s++;\r\n    }<\/pre>\n<p>In my books and courses, I explain that <code>*s!='\\0'<\/code> isn&#8217;t necessary because when <code>*s<\/code> evaluates to the null character, the condition is interpreted as FALSE. Further you can combine the loop&#8217;s statements to <code>putchar(*s++)<\/code>, then one thing becomes another, and soon the entire loop is its own condition.<\/p>\n<p>The <code>*s!='\\0'<\/code> condition isn&#8217;t enough, however. That&#8217;s because <em>putchar()<\/em> returns an <em>int<\/em> value, which can also be the <code>EOF<\/code> or a file error. The following update to the code accounts for these conditions:<\/p>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n  \r\nint main()\r\n{\r\n    char hello[] = \"Greetings, Human!\\n\";\r\n    char *s;\r\n    int out;\r\n\r\n    s = hello;\r\n    while( *s != '\\0' )\r\n    {\r\n        out = putchar(*s);\r\n        if( out==EOF || ferror(stdout) )\r\n        {\r\n            puts(\"\\nFile error\");\r\n            clearerr(stdout);\r\n            return(1);\r\n        }\r\n        s++;\r\n    }\r\n\r\n    return(0);\r\n}<\/pre>\n<p>To avoid having to cram too much into the <em>while<\/em> loop&#8217;s condition, I placed the <em>putchar()<\/em> statement into the loop itself. The value returned is saved in the <code>out<\/code> variable. That return value is compared with the <code>EOF<\/code>, along with the <em>ferror()<\/em> value on the standard output device. When either situation occurs, an error message is displayed, the standard output device cleared of errors, and the program stops.<\/p>\n<p>This version of code is safer than the original because it handles any potential error output. (For details on handling file errors refer to <a href=\"http:\/\/c-for-dummies.com\/blog\/?p=1726\">this post<\/a>.) A problem I had with simulating such errors is that the shell catches most of them before the code has a chance to screw up. Still, if a file became corrupt after output redirection or some other disaster took place, the code would neatly exit, which is the entire point of safe coding practices.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>It may seem unlikely, but the <em>putchar()<\/em> function can return a file error. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=2871\">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-2871","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\/2871","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=2871"}],"version-history":[{"count":5,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2871\/revisions"}],"predecessor-version":[{"id":2881,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2871\/revisions\/2881"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2871"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2871"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2871"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}