Thread: K&R detab

  1. #1
    Registered User
    Join Date
    Jul 2013
    Posts
    6

    K&R detab

    Hello all! This is my first thread! I actually signed up to post, because i saw that several people here on the forum have asked about this exercise in the past. Basically, the task is to replace tabs with spaces, ensuring that the number of spaces is appropriate to get you to the next tab stop (i.e. if you were only 4 spaces away from a tab stop, don't replace the tab with 8 spaces).

    Anyway, i'm not posting because i can't figure it out. I'm posting because i did figure it out, and i'm not sure if my code is good enough. I think all of the solutions i've seen have included character arrays, and many have included multiple functions. I realize the text says "these exercises suggest programs of somewhat greater complexity than the ones earlie in this chapter," but it seemed like a very straightfortward task.

    Have i oversimplified or something?

    Code:
    #include <stdio.h>
    
    #define TAB_STOP 8
    
    int main()
     {
      int c, i;
    
      c=0;
    
      for (i=TAB_STOP; (c=getchar()) != EOF; --i)
       {
        if (i<=0)
          i=TAB_STOP;
    
        if (c=='\n')
          i=TAB_STOP+1;
    
        if (c=='\t')
          while (i>0)
           {
            printf(" ");
            --i;
           }
        else
          putchar(c);
       }
    
      return 0;
     }

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,163
    What sort of testing did you do?

    For example, prepare a text file along these lines
    <tab>hello
    <sp><tab>hello
    <sp><sp><tab>hello
    <sp><sp><sp><tab>hello
    <sp><sp><sp><sp><tab>hello

    save it as say testinput.txt

    and then invoke your program with
    myprog < testinput.txt
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Jul 2013
    Posts
    6
    For testing i made a file called testdata, which was something like

    1234<tab>123<tab>1
    <tab>123456789<tab>1
    <tab><tab>12345678<tab>1

    Then i ran
    detab < testdata > output

    The two main difficulties i had were getting the main cycle to run right and getting line breaks to work properly. I just noticed there's an artifact of the former still in my code; the reset for i (first if statement) checks i <= 0. Originally, i had the tab replacement loop decrement while i>=0, which gave me a -1 endpoint. I should change it to i==0 but it's harmless as is.

    The second problem was line breaks. The first line was always fine, but following lines were always offset by one character. I figured out it was because the reset shouldn't happen on \n but rather at the beginning of the next line. The "TAB_STOP+1" bit is a fix for that. I feel like that's really inelegant, but i couldn't think of a better way.
    Last edited by JTG; 07-14-2013 at 09:31 AM.

  4. #4
    young grasshopper jwroblewski44's Avatar
    Join Date
    May 2012
    Location
    Where the sidewalk ends
    Posts
    294
    one thing I noticed is that you aren't subtracting from tabstop when you print a character that isn't a tab. as you get closer and closer to the tabstop point, the number of spaces needed to reach the tabstop point decreases at the same rate.
    "Simplicity is the ultimate sophistication." - Leonardo da Vinci

  5. #5
    Registered User
    Join Date
    Jul 2013
    Posts
    6
    Both loops are decrementing i.

    The outer loop, which is pulling input, decrements i in its declaration statement. There's an if statement inside that resets i to the defined tab length when it hits 0. This way, the count just keeps resetting itself until it hits a tab, and the value of i at that point is the number of spaces needed.

    The while loop takes that value and decrements as well, printing spaces until the counter hits 0. At this point, the outer loop picks back up, and the leading if statement resets to 8 in case there are consecutive tabs

  6. #6
    young grasshopper jwroblewski44's Avatar
    Join Date
    May 2012
    Location
    Where the sidewalk ends
    Posts
    294
    im sorry, you are correct.
    "Simplicity is the ultimate sophistication." - Leonardo da Vinci

  7. #7
    Registered User
    Join Date
    Jul 2013
    Posts
    6
    My initial question wasn't about finding a valid solution; it was more about whether my approach in solving the problem looks good enough. I am learning C now and want to be sure i'm forming good habits for later.

    I wasn't sure if i should split the program into a couple of functions (as the textbook seems to suggest) or if it's fine as-is since it's so short. I guess i could have done something like this:
    Code:
        if (c=='\t')
          i=addspaces(i);
        else
          putchar(c);
    ...but it seemed silly to me to make a new function that only holds a single loop.

  8. #8
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    but it seemed silly to me to make a new function that only holds a single loop.
    Nothing silly about that.

    To develop the program more, make it so the user can enter a tab size from the command line.
    If they run it without giving a size, then use the default of 8.
    Deal with the command line in main and pass off the tabsize to a separate detab function.

  9. #9
    young grasshopper jwroblewski44's Avatar
    Join Date
    May 2012
    Location
    Where the sidewalk ends
    Posts
    294
    If you ask me, your solutions simplicity is a good thing. With small programs like this, moving a one liner into a function is simply a matter of preference. But when your code portions start to repeat themselves, that should be a sign to move the code chunk into a function.
    "Simplicity is the ultimate sophistication." - Leonardo da Vinci

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Detab - K&R Exercise
    By jwroblewski44 in forum C Programming
    Replies: 7
    Last Post: 05-22-2012, 10:15 PM
  2. detab---improper spacing
    By dgoodmaniii in forum C Programming
    Replies: 2
    Last Post: 11-15-2009, 08:15 AM
  3. Detab Function Loop Hang
    By neu_greg in forum C Programming
    Replies: 6
    Last Post: 01-27-2009, 05:33 PM