{"id":702,"date":"2014-05-24T00:01:16","date_gmt":"2014-05-24T07:01:16","guid":{"rendered":"http:\/\/c-for-dummies.com\/blog\/?p=702"},"modified":"2014-05-31T07:45:21","modified_gmt":"2014-05-31T14:45:21","slug":"word-wrap-filter-walkthrough","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=702","title":{"rendered":"Word Wrap Filter Walkthrough"},"content":{"rendered":"<p>In last week&#8217;s <a href=\"http:\/\/c-for-dummies.com\/blog\/?p=689\">Lesson<\/a>, I presented code that shows one way to wrap incoming streaming text. It&#8217;s not the easiest thing. Let me explain how last week&#8217;s code attempts to solve the problem.<br \/>\n<!--more--><br \/>\nHere&#8217;s a copy of the word wrap filter code from last week&#8217;s Lesson:<\/p>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n#include &lt;ctype.h&gt;\r\n\r\nint main()\r\n{\r\n    char *buffer,*space;\r\n    int c,x,right_margin,position;\r\n\r\n    right_margin = 40;      <span class=\"comments\">\/* make the margin variable *\/<\/span>\r\n\r\n    <span class=\"comments\">\/* allocate space for the buffer *\/<\/span>\r\n    buffer = malloc(sizeof(char) * right_margin);\r\n    if(buffer==NULL)\r\n    {\r\n        perror(\"Unable to allocate buffer\");\r\n        exit(1);\r\n    }\r\n\r\n    *buffer = '\\0';         <span class=\"comments\">\/* initialize buffer *\/<\/span>\r\n    space = buffer;         <span class=\"comments\">\/* Initialize space *\/<\/span>\r\n    position = 0;           <span class=\"comments\">\/*  and position *\/<\/span>\r\n    c = 65;                 <span class=\"comments\">\/* Ensure that it loops *\/<\/span>\r\n    while(c)\r\n    {\r\n        c = getchar();          <span class=\"comments\">\/* fetch character *\/<\/span>\r\n        *(buffer+position) = c; <span class=\"comments\">\/* store character *\/<\/span>\r\n        <span class=\"comments\">\/* if c is white space, save its location *\/<\/span>\r\n        if(isspace(c))\r\n            space = buffer+position;\r\n        position++;             <span class=\"comments\">\/* buffer index *\/<\/span>\r\n        <span class=\"comments\">\/* check to see if the margin has been reached *\/<\/span>\r\n        if(position &gt; right_margin)\r\n        {\r\n            <span class=\"comments\">\/* Display the buffer up to the space *\/<\/span>\r\n            for(x=0;x&lt;right_margin;x++)\r\n            {\r\n                if( *(buffer+x)==EOF)   <span class=\"comments\">\/* exit on EOF *\/<\/span>\r\n                    exit(0);\r\n                if(buffer+x == space)   <span class=\"comments\">\/* stop at w\/s char *\/<\/span>\r\n                    break;\r\n                putchar(*(buffer+x));\r\n            }\r\n            putchar('\\n');\r\n            <span class=\"comments\">\/* copy the rest of the buffer to the start *\/<\/span>\r\n            position = 0;\r\n            space++;\r\n            while(space &lt;= buffer+right_margin)\r\n            {\r\n                *(buffer+position) = *(space);\r\n                position++;\r\n                space++;\r\n            }\r\n            <span class=\"comments\">\/* Re-initialize the space pointer *\/<\/span>\r\n            space = buffer;\r\n        }\r\n    }\r\n\r\n    return(0);\r\n}<\/pre>\n<p>To assist you in understanding how the code works, I&#8217;ve concocted the following video presentation. Review the video and then read my commentary to see how the code works.<\/p>\n<div align=\"center\">\n<iframe loading=\"lazy\" width=\"600\" height=\"300\" class=\"tscplayer_inline\" name=\"tsc_player\" src=\"\/blog\/video\/blog0523\/blog0523_player.html\" scrolling=\"no\" frameborder=\"0\" webkitallowfullscreen mozallowfullscreen allowfullscreen><\/iframe>\n<\/div>\n<p>The video explains how the code operates at a philosophical level. It uses the same variables names as shown in the code:<\/p>\n<p>The <code>right_margin<\/code> variable is set at Line 10. You can set it to any value at which you want to wrap input. The <code>buffer<\/code> is then created by <em>malloc()<\/em> at Line 13, its size set equal to <code>right_margin<\/code>.<\/p>\n<p>Line 20 initializes the <code>buffer<\/code>, setting it to a zero-length string.<\/p>\n<p>Line 21 initializes the space pointer, setting it equal to the start of the buffer.<\/p>\n<p>The <code>position<\/code> variable (it&#8217;s not a pointer, which is hinted at in the video) is initialized at Line 22.<\/p>\n<p>Line 23 sets the value of the <code>c<\/code> variable, which ensures that the loop runs at least once; there&#8217;s always an off-chance that <code>c<\/code> could be randomly initialized to the <em>EOF<\/em> character, which would stifle the program&#8217;s output.<\/p>\n<p>The <em>if<\/em> test at Line 29 is used to set the location of the <code>space<\/code> pointer, hopping it down the <code>buffer<\/code> from one white space character to another.<\/p>\n<p>The <code>right_margin<\/code> test happens at Line 33.<\/p>\n<p>The <em>if<\/em> test at Line 38 fixes an error that might occur when the <em>EOF<\/em> character is read before the <code>buffer<\/code> is filled. Otherwise the entire <code>buffer<\/code> is displayed.<\/p>\n<p>A <em>while<\/em> loop at Line 48 copies the remaining text from the end of the <code>buffer<\/code> to the start. Again, the <code>position<\/code> variable isn&#8217;t a pointer, but it&#8217;s used with the <code>buffer<\/code> pointer to assist in copying the remaining characters.<\/p>\n<p>And it all repeats until an <em>EOF<\/em> is encountered.<\/p>\n<p>Now that I&#8217;ve written all that, and the code does run, I confess that it&#8217;s not perfect: Two conditions exist where this code fails to properly wrap text.<\/p>\n<p>The first condition where this code fails is when a newline character is found within the text. The second condition occurs when the text contains no white space characters on which to wrap. Solutions for both situations will be presented in <a href=\"http:\/\/c-for-dummies.com\/blog\/?p=724\">next week&#8217;s Lesson<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Writing a word wrap filter is complex. Here&#8217;s an explanation of how it works. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=702\">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-702","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\/702","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=702"}],"version-history":[{"count":9,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/702\/revisions"}],"predecessor-version":[{"id":756,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/702\/revisions\/756"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=702"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=702"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=702"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}