{"id":14142,"date":"2026-05-20T03:00:00","date_gmt":"2026-05-20T07:00:00","guid":{"rendered":"https:\/\/www.both.org\/?p=14142"},"modified":"2026-05-02T20:19:18","modified_gmt":"2026-05-03T00:19:18","slug":"converting-tabs-to-spaces","status":"publish","type":"post","link":"https:\/\/www.both.org\/?p=14142","title":{"rendered":"Converting tabs to spaces"},"content":{"rendered":"<div class=\"pld-like-dislike-wrap pld-template-1\">\r\n    <div class=\"pld-like-wrap  pld-common-wrap\">\r\n    <a href=\"javascript:void(0)\" class=\"pld-like-trigger pld-like-dislike-trigger  \" title=\"\" data-post-id=\"14142\" data-trigger-type=\"like\" data-restriction=\"cookie\" data-already-liked=\"0\">\r\n                        <i class=\"fas fa-thumbs-up\"><\/i>\r\n                <\/a>\r\n    <span class=\"pld-like-count-wrap pld-count-wrap\">    <\/span>\r\n<\/div><\/div>\n<p>You don&#8217;t have to go far in certain programming circles before you find the classic &#8220;tabs versus spaces&#8221; argument. Some people like to use tabs to provide indenting in their program source code; others live like animals and use spaces. You can see which side of the fence I live on.<\/p>\n\n\n\n<p>I&#8217;m joking! I might use tabs to indent my code when I&#8217;m working in the editor, then convert those tabs to spaces when I need to share my work with someone else. The <strong>indent<\/strong> program can reformat C source files, including changing tabs to spaces.<\/p>\n\n\n\n<p>But if you need to work with other files that aren&#8217;t source code, you need another tool. The <strong>expand<\/strong> command is a standard Unix program that should be available on every Linux system. This command converts tabs to spaces. For example, I often use <strong>expand<\/strong> if I need to display the contents of a file in an article or book chapter; those tabs can &#8220;get in the way&#8221; in a publishing system.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"writing-your-own\">Writing your own<\/h2>\n\n\n\n<p>If you&#8217;ve ever wondered how the <strong>expand<\/strong> program works, it&#8217;s not a very difficult program to write on your own. Writing your own version also means you can create a similar program for other operating systems that lack an <strong>expand<\/strong> command, such as DOS.<\/p>\n\n\n\n<p>Let&#8217;s call our program <strong>untab<\/strong> because it will convert tabs to spaces. The program only needs to track a few things: how &#8220;wide&#8221; is a tab, what column it&#8217;s printing to, and what character to print. In the simplest case, we can use a constant value for the tab width, as <code>TABSIZE<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#define TABSIZE 8<\/code><\/pre>\n\n\n\n<p>The other values can be tracked as variables in a program: <code>c<\/code> for the character to print, and <code>col<\/code> for the column it&#8217;s printing to.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    short col = TABSIZE;\n    int c;<\/code><\/pre>\n\n\n\n<p>We can get away with a <code>short<\/code> variable type for the column, because it will only track values up to 8. However, the <code>c<\/code> variable needs to be an <code>int<\/code> because that&#8217;s how C reads characters one at a time from a file.<\/p>\n\n\n\n<p>The program can read a file one character at a time. As it prints each character, the program needs to track what column it&#8217;s in. This is just a matter of incrementing a counter, until the program encounters a tab. For a tab, it needs to expand the tab into spaces:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    while ((c = getchar()) != EOF) {\n        if (c == '\\t') {\n            while (col &gt; 0) {\n                putchar(' ');\n                col--;\n            }\n        }\n        else {\n            putchar(c);\n            col--;\n        }\n\n        if ((c == '\\n') || (col == 0)) {\n            col = TABSIZE;\n        }\n    }<\/code><\/pre>\n\n\n\n<p>Actually, the program doesn&#8217;t need to track the <em>actual column<\/em> that it&#8217;s printing to. Instead, it can simply track <em>how many spaces until the next tab stop<\/em>, and count <em>down<\/em> to the next tab stop. That&#8217;s why every time the program prints a character, it subtracts one from the <code>col<\/code> variable.<\/p>\n\n\n\n<p>If the program finds the end of a line, or when the program reaches the next tab stop, it resets the <code>col<\/code> counter to the tab size, ready to count down to the <em>next<\/em> tab stop.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"putting-it-all-together\">Putting it all together<\/h2>\n\n\n\n<p>Let&#8217;s put everything together into one source file, so we can compile our own program that expands tabs to spaces. Save this as <code>untab.c<\/code> on your system:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;stdio.h&gt;\n\n#define TABSIZE 8\n\nint main()\n{\n    short col = TABSIZE;\n    int c;\n\n    while ((c = getchar()) != EOF) {\n        if (c == '\\t') {\n            while (col &gt; 0) {\n                putchar(' ');\n                col--;\n            }\n        }\n        else {\n            putchar(c);\n            col--;\n        }\n\n        if ((c == '\\n') || (col == 0)) {\n            col = TABSIZE;\n        }\n    }\n\n    return 0;\n}<\/code><\/pre>\n\n\n\n<p>Compile it using your favorite C compiler, such as GCC on Linux. This is a very simple program, so you don&#8217;t need a special compiler or library to make it work:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ gcc -o untab untab.c<\/code><\/pre>\n\n\n\n<p>Now we need to test the program. It&#8217;s difficult to show a test file <em>that has tabs in it<\/em> in an article like this, so let&#8217;s work around that limitation by writing a file that uses a different character that we can turn into a tab later using the <strong>tr<\/strong> command. In this case, let&#8217;s use <code>#<\/code> as a &#8220;tab&#8221; placeholder:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>123456789012345678901234567890\n#|tab#|tab#|tab\n,,,,,,,,|space,,|space,,|space\na#|tab##|tab\nb,,,,,,,|space,,,,,,,,,,|space\na##|tab#|tab\nb,,,,,,,,,,,,,,,|space,,|space<\/code><\/pre>\n\n\n\n<p>Save this file as <code>tab.txt<\/code>. I&#8217;ve started the test file with a list of numbers so you can see the first 30 columns. For each line with a tab, I&#8217;ve also written another line that has the correct number of extra spaces (typed as commas) to reach the next tab stop.<\/p>\n\n\n\n<p>If you convert the <code>#<\/code> placeholders to tabs, then run the output through the new <strong>untab<\/strong> program, everything should line up:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ tr '#' '\\t' &lt; tab.txt | .\/untab\n123456789012345678901234567890\n        |tab    |tab    |tab\n,,,,,,,,|space,,|space,,|space\na       |tab            |tab\nb,,,,,,,|space,,,,,,,,,,|space\na               |tab    |tab\nb,,,,,,,,,,,,,,,|space,,|space<\/code><\/pre>\n\n\n\n<p>We can verify that this is the correct behavior by replacing the <strong>untab<\/strong> program with the standard <strong>expand<\/strong> program:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ tr '#' '\\t' &lt; tab.txt | expand\n123456789012345678901234567890\n        |tab    |tab    |tab\n,,,,,,,,|space,,|space,,|space\na       |tab            |tab\nb,,,,,,,|space,,,,,,,,,,|space\na               |tab    |tab\nb,,,,,,,,,,,,,,,|space,,|space<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"how-it-works\">Make it your own<\/h2>\n\n\n\n<p>A program like this one is a great starting point if you want to learn about programming. There&#8217;s not much going on here; the program only needs to keep track of a few values, and is quite short, but it performs a very useful function to translate text files.<\/p>\n\n\n\n<p>If you want to learn about programming, try adapting this program to add other features. For example, you could replace <code>TABSIZE<\/code> with a variable, and use a command line value to set the tab size. That makes the program more useful, especially if you prefer to have tabs displayed as four spaces instead of eight spaces. Feel free to make this program your own.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Learn how to write your own version of the &#8216;expand&#8217; program, to convert tabs to spaces<\/p>\n","protected":false},"author":33,"featured_media":3096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_lmt_disableupdate":"","_lmt_disable":"","footnotes":""},"categories":[5,150],"tags":[91,152],"class_list":["post-14142","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-linux","category-programming","tag-linux","tag-programming"],"modified_by":"Jim Hall","_links":{"self":[{"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/14142","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/users\/33"}],"replies":[{"embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=14142"}],"version-history":[{"count":2,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/14142\/revisions"}],"predecessor-version":[{"id":14144,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/posts\/14142\/revisions\/14144"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=\/wp\/v2\/media\/3096"}],"wp:attachment":[{"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=14142"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=14142"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.both.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=14142"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}