{"id":2804,"date":"2017-12-16T00:01:33","date_gmt":"2017-12-16T08:01:33","guid":{"rendered":"http:\/\/c-for-dummies.com\/blog\/?p=2804"},"modified":"2017-12-18T21:05:27","modified_gmt":"2017-12-19T05:05:27","slug":"safe-coding-practices-getchar-and-putchar","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=2804","title":{"rendered":"Safe Coding Practices &#8211; <em>getchar()<\/em> and <em>putchar()<\/em>"},"content":{"rendered":"<p>I confess that I get sloppy with <em>getchar()<\/em> and <em>putchar()<\/em>. These are macros, not functions, but the issue is that their return value is an <em>int<\/em>, not a <em>char<\/em> variable. The reason why is important if you want to follow <a href=\"http:\/\/c-for-dummies.com\/blog\/?p=2797\">safe coding practices<\/a>.<br \/>\n<!--more--><br \/>\nThe <em>getchar()<\/em> and <em>putchar()<\/em> functions return an <em>int<\/em> is because they&#8217;re stream-oriented and can interact with files. Keyboard input provides <em>char<\/em> values, but file input can generate <em>int<\/em> values, such as the <code>EOF<\/code> or End of File value, which is an <em>int<\/em>. And file output can generate <em>int<\/em> values on file errors. Safe coding practices dictate that you consider these conditions.<\/p>\n<p>The following code is a simple I\/O filter:<\/p>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n  \r\nint main()\r\n{\r\n    int ch;\r\n\r\n    while(1)\r\n    {\r\n        ch = getchar();\r\n        putchar(ch);\r\n    }\r\n\r\n    return(0);\r\n}<\/pre>\n<p>Both <em>getchar()<\/em> and <em>putchar()<\/em> use <em>int<\/em> variable <code>ch<\/code>, which is proper. If you run the program, you see everything input echoed back to output, as in:<\/p>\n<p><code>hello<br \/>\nhello<\/code><\/p>\n<p>If you type the <code>EOF<\/code> character, however, you get unpredictable results. <code>EOF<\/code> is Ctrl+D in most Unix shells, Ctrl+Z in Windows.<\/p>\n<p>Further, if you use the filter to pipe file input, you see all sorts of wackiness:<\/p>\n<p><code>cat file.txt | getputfilter<\/code><\/p>\n<p>Above, <code>file.txt<\/code> is a text file and <code>getputfilter<\/code> is the program compiled with the source code example. If <code>file.txt<\/code> exists, the program doesn&#8217;t stop because the <code>EOF<\/code> is never tested for in the code. If <code>file.txt<\/code> doesn&#8217;t exist, the program does whatever as the non-existent file error isn&#8217;t captured. Obviously, the code needs improvements &mdash; it needs some safe coding practices implemented.<\/p>\n<p>First, to test for the <code>EOF<\/code>, I modified the code as shown below:<\/p>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n  \r\nint main()\r\n{\r\n    int ch;\r\n\r\n    while(1)\r\n    {\r\n        ch = getchar();\r\n        if( ch == EOF)\r\n        {\r\n            if( ferror(stdin) )\r\n            {\r\n                puts(\"\\nEnd of File\");\r\n                clearerr(stdin);\r\n                return(0);\r\n            }\r\n        }\r\n        putchar(ch);\r\n    }\r\n\r\n    return(0);\r\n}<\/pre>\n<p>The <code>if(ch==EOF)<\/code> statement tests for the <code>EOF<\/code> character. When <code>EOF<\/code> is encountered, the <em>feof()<\/em> function confirms it, specifically for the <em>stdin<\/em> &#8220;file.&#8221; If so, the text <code>End of File<\/code> is output, the error is cleared for standard input, and the program terminates with a <em>return<\/em> statement.<\/p>\n<p>After you make the changes and compile the code, the program accurately spies the <code>EOF<\/code> character and doesn&#8217;t run amok.<\/p>\n<p>You can further bolster the code by using a <em>ferror(stdin)<\/em> statement. Refer to my <a href=\"http:\/\/c-for-dummies.com\/blog\/?p=1726\">Lessons on the <code>errno<\/code> variable<\/a> for more details on what you can do to further capture file I\/O errors for <em>getchar()<\/em> and <em>putchar()<\/em>.<\/p>\n<p>As with <em>getchar()<\/em>, the <em>putchar()<\/em> function can suffer from file errors as well, specifically with regards to redirected output that may go to an invalid file. I demonstrate an example in next week&#8217;s Lesson.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Beware the endless loop! <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=2804\">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-2804","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\/2804","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=2804"}],"version-history":[{"count":8,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2804\/revisions"}],"predecessor-version":[{"id":2885,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2804\/revisions\/2885"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2804"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2804"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2804"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}