{"id":7141,"date":"2025-09-08T00:01:36","date_gmt":"2025-09-08T07:01:36","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=7141"},"modified":"2025-09-06T14:14:06","modified_gmt":"2025-09-06T21:14:06","slug":"the-reversing-words-filter-solution","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=7141","title":{"rendered":"The Reversing Words Filter &#8211; Solution"},"content":{"rendered":"<p>The task for <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=7132\">this month&#8217;s C programming Exercise<\/a> is to code a filter that reverses single words. As a filter, the code deals with standard input and output, but it must store this input in word-sized chunks for the reversing process to work.<br \/>\n<!--more--><br \/>\nI asked Google how long the longest word is in the English language. It replied that pneumonoultramicroscopicsilicovolcanoconiosis is 45 letters long. So for a word-reversing filter to work, I need a buffer that holds at least 46 characters (pneumonoultramicroscopicsilicovolcanoconiosis plus the null character). Other human languages may require a larger buffer, but the technique works the same.<\/p>\n<p>Here is my solution:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2025_09-Exercise.c\" rel=\"noopener\" target=\"_blank\">2025_09-Exercise.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;ctype.h&gt;\r\n\r\nint main()\r\n{\r\n    <span class=\"comments\">\/* the longest legitimate word in English\r\n       is about 45 characters *\/<\/span>\r\n    const int longest = 64;\r\n    int ch,offset;\r\n    char word[longest];\r\n\r\n    offset = 0;\r\n    while( (ch=getc(stdin)) != EOF )\r\n    {\r\n        <span class=\"comments\">\/* store alphabetic words *\/<\/span>\r\n        if( isalnum(ch) || ch=='\\'' )\r\n        {\r\n            word[offset] = ch;\r\n            offset++;\r\n            <span class=\"comments\">\/* check for overflow *\/<\/span>\r\n            if( offset==longest )\r\n            {\r\n                fprintf(stderr,\"\\nInput overflow\\n\");\r\n                return 1;\r\n            }\r\n        }\r\n        else\r\n        {\r\n            <span class=\"comments\">\/* if the buffer has content, output\r\n               it backwards *\/<\/span>\r\n            while(offset&gt;0)\r\n            {\r\n                offset--;\r\n                putc(word[offset],stdout);\r\n            }\r\n            <span class=\"comments\">\/* output the non-alpha character *\/<\/span>\r\n            putc(ch,stdout);\r\n        }\r\n    }\r\n\r\n    return 0;\r\n}<\/pre>\n<p>Constant <em>int<\/em> variable <code>longest<\/code> sets the size of the buffer, with more than enough room for pneumonoultramicroscopicsilicovolcanoconiosis. Integer variable <code>ch<\/code> gobbles input. Variable <code>offset<\/code> tracks word length. Buffer <code>word[]<\/code> holds words as they&#8217;re input.<\/p>\n<p>The <em>while<\/em> loop fetches standard input until the EOF (end-of-file) is encountered, which is a typical construction for a filter. The loop&#8217;s <em>if-else<\/em> structure tracks words input, storage, and output.<\/p>\n<p>The <em>if<\/em> condition uses the <em>isalnum()<\/em> ctype function to test for alphanumeric characters. The <code>||<\/code> (OR) test checks for the apostrophe to catch contractions and possessives. When the <em>if<\/em> condition is true, the character input is stored in the <code>word[]<\/code> buffer. Variable <code>offset<\/code> is incremented. A nested <em>if<\/em> test checks for overflow just in case. If so, the program terminates.<\/p>\n<p>The <em>else<\/em> part of the construction deals with non-alphanumeric character input. First, a <em>while<\/em> loop empties any text stored in the <code>word[]<\/code> buffer. The looping condition is <code>offset&gt;0<\/code>, so this loop is skipped when the buffer is empty. Otherwise, text in <code>word[]<\/code> is output one character at a time, using variable <code>offset<\/code> to work backwards through the buffer.<\/p>\n<p>Whether the <em>while<\/em> loop outputs a backwards word or not, the next statement outputs the non-alpha\/apostrophe character caught by the <em>else<\/em> condition. Variable <code>offset<\/code> is equal to zero at this point, which primes the next spin of the main <em>while<\/em> loop to potentially store the next word.<\/p>\n<p>Here&#8217;s a sample run:<\/p>\n<p><code>Here's a sample run:<br \/>\ns'ereH a elpmas nur:<\/code><\/p>\n<p>And, of course:<\/p>\n<p><code>pneumonoultramicroscopicsilicovolcanoconiosis<br \/>\nsisoinoconaclovociliscipocsorcimartluonomuenp<\/code><\/p>\n<p>Finally:<\/p>\n<p><code>The word pneumonoultramicroscopicsilicovolcanoconiosis is a long word<br \/>\nehT drow sisoinoconaclovociliscipocsorcimartluonomuenp si a gnol drow<\/code><\/p>\n<p>This code took me a few tries to get perfect. One of my drafts output null characters after each reversed word. This output was related to the value of variable <code>offset<\/code> being decremented after the character was output. Null characters don&#8217;t appear on the screen. To ensure that your code doesn&#8217;t output null characters, run it through a program like <em>hexdump<\/em> and watch for those little 00 bytes.<\/p>\n<p>I hope that your solution met with success!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The task for this month&#8217;s C programming Exercise is to code a filter that reverses single words. As a filter, the code deals with standard input and output, but it must store this input in word-sized chunks for the reversing &hellip; <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=7141\">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":[5],"tags":[],"class_list":["post-7141","post","type-post","status-publish","format-standard","hentry","category-solution"],"_links":{"self":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/7141","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=7141"}],"version-history":[{"count":4,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/7141\/revisions"}],"predecessor-version":[{"id":7159,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/7141\/revisions\/7159"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=7141"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=7141"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=7141"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}