{"id":409,"date":"2013-11-30T00:01:07","date_gmt":"2013-11-30T08:01:07","guid":{"rendered":"http:\/\/c-for-dummies.com\/blog\/?p=409"},"modified":"2013-12-28T08:42:35","modified_gmt":"2013-12-28T16:42:35","slug":"variable-tab-width","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=409","title":{"rendered":"Variable Tab Width, Part I"},"content":{"rendered":"<p>The tab character, <code>0x08<\/code> or ^I (Control-I), is always the same width, no?<br \/>\n<!--more--><br \/>\nIf you write a program and include a tab character in the output, can you always expect that tab to line up your text? Hopefully! Not every terminal is the same, but that&#8217;s a mandate that&#8217;s pretty much been forgotten. The old and various teletypes and VDUs of the 1970s are pretty much gone now, but as a programmer, you can code in flexibility.<\/p>\n<p>Here&#8217;s an example:<\/p>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n\r\nint main()\r\n{\r\n    char *text[3] = {\r\n      \"\\tHello\\tHello\",\r\n      \"\\tHi\\tHi\",\r\n      \"\\tFelicitations\\tFelicitations\"\r\n    };\r\n    int x;\r\n\r\n    for(x=0;x<3;x++)\r\n        printf(\"%s\\n\",text[x]);\r\n\r\n    return(0);\r\n}<\/pre>\n<p>The code above displays three strings, each of which has two tab characters, <code>\\t<\/code>, and other text of varying length. Here's the output:<\/p>\n<pre><code>\tHello\tHello\r\n\tHi\tHi\r\n\tFelicitations\tFelicitations<\/code><\/pre>\n<p>The long word <code>Felicitations<\/code> messes up the otherwise neat columns generated by the tabs. That's to be expected; anyone who's formatted documents on a computer has faced that problem when dealing with fixed-width tab stops. Above, and on most terminals, the tab stops are set every 8 characters.<\/p>\n<p>Of course, you won't find any fixed tab stops across a terminal window; it's the terminal output routines that calculate tab stops. Also, you'll note that the tab character isn't just 8 consecutive spaces. The width varies, depending on the cursor's horizontal position.<\/p>\n<p>If you wanted to code your own tab stop routine, you'd have to start by modifying the code so that it outputs one character at a time. That makes it easier to fetch and deal with a tab character. Here's the first step in the modification:<\/p>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n\r\nint main()\r\n{\r\n    char *text[3] = {\r\n      \"\\tHello\\tHello\",\r\n      \"\\tHi\\tHi\",\r\n      \"\\tFelicitations\\tFelicitations\"\r\n    };\r\n    int x,i;\r\n\r\n    for(x=0;x<3;x++)\r\n    {\r\n        i = 0;\r\n        while(*(text[x]+i))\r\n        {\r\n            putchar(*(text[x]+i));\r\n            i++;\r\n        }\r\n        putchar('\\n');\r\n    }\r\n\r\n    return(0);\r\n}<\/pre>\n<p>Above, I've replaced the <em>printf()<\/em> function with a <em>while()<\/em> loop that churns through the string, one character at a time. The <em>putchar()<\/em> function handles display of each character. A second <em>putchar()<\/em> handles the newline.<\/p>\n<p>The second step is to isolate the tab character and whisk it off to a function for separate handling. This modification handles that step by employing the <em>tabby()<\/em> function:<\/p>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n\r\nvoid tabby(void);\r\n\r\nint main()\r\n{\r\n    char *text[3] = {\r\n      \"\\tHello\\tHello\",\r\n      \"\\tHi\\tHi\",\r\n      \"\\tFelicitations\\tFelicitations\"\r\n    };\r\n    int x,i;\r\n\r\n    for(x=0;x<3;x++)\r\n    {\r\n        i = 0;\r\n        while(*(text[x]+i))\r\n        {\r\n            if( *(text[x]+i) == '\\t')\r\n                tabby();\r\n            else\r\n                putchar(*(text[x]+i));\r\n            i++;\r\n        }\r\n        putchar('\\n');\r\n    }\r\n\r\n    return(0);\r\n}\r\n\r\n\/* calculate and display a tab *\/\r\nvoid tabby(void)\r\n{\r\n    putchar('\\t');\r\n}<\/pre>\n<p>At this stage in the process, the <em>tabby()<\/em> function merely displays the  tab character <code>\\t<\/code>. The code's output is still the same as the first example, but the <em>tabby()<\/em> function is primed for a better solution. I'll cover one such solution in <a href=\"http:\/\/c-for-dummies.com\/blog\/?p=424\">next week's Lesson<\/a>, although you're free to concoct your own in the meantime.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The width represented by the tab character isn&#8217;t always 8 spaces wide. It can vary. You can write code to prove it. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=409\">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-409","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\/409","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=409"}],"version-history":[{"count":10,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/409\/revisions"}],"predecessor-version":[{"id":497,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/409\/revisions\/497"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=409"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=409"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=409"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}