{"id":682,"date":"2014-05-10T00:01:22","date_gmt":"2014-05-10T07:01:22","guid":{"rendered":"http:\/\/c-for-dummies.com\/blog\/?p=682"},"modified":"2014-05-17T07:08:25","modified_gmt":"2014-05-17T14:08:25","slug":"wrapping-static-text","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=682","title":{"rendered":"Wrapping Static Text"},"content":{"rendered":"<p>When displaying a long string of text, it&#8217;s polite &#8212; and expected &#8212; for the programmer to <em>wrap<\/em> the text. Not wrapping the text would split words at the right margin, which irritates human readers to no end.<br \/>\n<!--more--><br \/>\nLast week&#8217;s <a href=\"http:\/\/c-for-dummies.com\/blog\/?p=669\">Lesson<\/a> discussed basic word-wrap philosophy. It&#8217;s not that difficult of a concept to grasp, but it isn&#8217;t the easiest thing to code.<\/p>\n<p>As a review, here are the steps to wrap a word at the terminal&#8217;s right margin:<\/p>\n<ol>\n<li>If the character index (current column position) isn&#8217;t yet at the margin, keep reading characters. Otherwise:<\/li>\n<li>Backup to locate the nearest white space character.<\/li>\n<li>Replace that whitespace character with a newline.<\/li>\n<li>Start the next line with the text you backed over. (This is the tricky part.)<\/li>\n<li>Start over.<\/li>\n<\/ol>\n<p>The following code demonstrates one way that these steps can be used to wrap static text, or text that&#8217;s already presented within the code.<\/p>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;ctype.h&gt;\r\n#include &lt;string.h&gt;\r\n\r\n#define COLUMN 40\r\n\r\nint main()\r\n{\r\n    char preamble[] = \"We the People of the United States, in Order to form a more perfect Union, establish Justice, insure domestic Tranquility, provide for the common defense, promote the general Welfare, and secure the Blessings of Liberty to ourselves and our Posterity, do ordain and establish this Constitution for the United States of America.\";\r\n    char *base,*right_margin;\r\n    int length,width;\r\n\r\n    length = strlen(preamble);\r\n    base = preamble;\r\n    width = COLUMN;\r\n\r\n    while(*base)\r\n    {\r\n        if(length <= width)\r\n        {\r\n            puts(base);     \/* display string *\/\r\n            return(0);      \/* and leave *\/\r\n        }\r\n        right_margin = base+width;\r\n        while(!isspace(*right_margin))\r\n        {\r\n            right_margin--;\r\n            if( right_margin == base)\r\n            {\r\n                right_margin += width;\r\n                while(!isspace(*right_margin))\r\n                {\r\n                    if( *right_margin == '\\0')\r\n                        break;\r\n                    right_margin++;\r\n                }\r\n            }\r\n        }\r\n        *right_margin = '\\0';\r\n        puts(base);\r\n        length -= right_margin-base+1;      \/* +1 for the space *\/\r\n        base = right_margin+1;\r\n    }\r\n\r\n    return(0);\r\n}<\/pre>\n<p>The <em>while<\/em> loop at Line 17 controls the word wrap process. It's actually a test: If the string represented by the <code>base<\/code> variable is empty, then nothing is wrapped.<\/p>\n<p>Within the loop, a test takes place at Line 19: If the string's length (obtained at Line 13) is shorter than the right margin (set in the <code>width<\/code> variable), then a <em>puts()<\/em> function displays the string and the program terminates. Done!<\/p>\n<p>Line 24 begins the wrapping process. At this point in the code, the text referenced by <em>char<\/em> pointer <code>base<\/code> is wider than the right column (the value stored in the <code>width<\/code> variable). The right margin position is referenced by this calculation:<\/p>\n<p><code>right_margin = base+width;<\/code><\/p>\n<p>So if the right margin is at 80 columns, the pointer <code>right_margin<\/code> is set 80 characters forward from the <code>base<\/code> pointer &mdash; effectively that's a line of text. But the line may terminate in the middle of a word, so the code attempts to find a white space character.<\/p>\n<p>The <em>while<\/em> loop at Line 25 is tasked with finding that white space character. The <em>isspace()<\/em> function helps locate the wrapping point. The <em>while<\/em> loop continues to spin as long as the character represented by pointer <code>right_margin<\/code> isn't a space.<\/p>\n<p>Line 27 backs up the pointer <code>right_margin<\/code> one character position, hunting for the wrapping point.<\/p>\n<p>The <em>if<\/em> test at Line 28 (going all the way to Line 37) checks for the rare condition that no spaces are found for wrapping the text. If so, the right margin is recalculated (Line 30), and a non-white space character is searched for <em>beyond<\/em> the right margin, which happens with the <em>while<\/em> loop at Line 31.<\/p>\n<p>At Line 39, the whitespace character is replaced by a null character, <code>\\0<\/code>. Then the <em>puts()<\/em> function at Line 40 displays the string, which at this point easily fits within the margin specified.<\/p>\n<p>Line 41 adjusts the value of the <code>length<\/code> variable, which is used at Line 19 to determine when the string no longer needs to be processed.<\/p>\n<p>Line 42 calculates the starting point for the rest of the string, and the <em>while<\/em> loop continues.<\/p>\n<p>Yes, this is some complex code! The basic wrapping function could be written in fewer lines, but this example handles two conditions that do arise: When the string is too short to wrap (Lines 19 through 23) and when a word is wider than the right margin (Lines 28 through 37).<\/p>\n<p><a href=\"http:\/\/c-for-dummies.com\/blog\/?p=689\">Next week's Lesson<\/a> demonstrates a way to wrap streaming text.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Here is one way to manipulating static text to wrap at a given right margin. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=682\">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-682","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\/682","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=682"}],"version-history":[{"count":5,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/682\/revisions"}],"predecessor-version":[{"id":733,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/682\/revisions\/733"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=682"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=682"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=682"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}