Program help

May 6, 2015 at 3:44pm
Good day to all,

I`m doing a self study of the C Programming language, Kernighan and Ritchie.
A very good introduction to programming, whether as first or second programming language.

My question is as follows:

Write a program detab that replaces tabs in the input with the proper number of blanks to space to the next tab stop. Assume a fixed set of tab stops, say every n columns. Should n be a variable or a symbolic parameter?

Naturally n should be a variable to allow modification at run time, but I`m not asking to implement the solution.

I just can`t get the question, what is column here? How many blanks should there be in one tab? Does it vary, if so how?
May 6, 2015 at 3:53pm
Column may just mean spaces. for example, a tab could be the same as 4 spaces.
May 6, 2015 at 7:47pm
That was intelligent.

¿ Should I replace every tab by a single or two blanks ?
May 6, 2015 at 8:04pm
From the sound of the question, the number of spaces used to replace a tab will vary based on where a tab occurs in a line.
Consider the following strings: "123456789", "12\tXY", "1\tXY", and "123\tXY" (where \t represents a tab). If those strings appear on consecutive lines, and a tab stop occurs every 8 columns, this is what the output would look like:
123456789
12      XY
1       XY
123     XY

Because of where a tab stop occurs, the "XY" parts line up right after the tab stop. You will have to figure out how far into a line you are, how far that puts you away from the next tab stop, and insert spaces accordingly.
Last edited on May 6, 2015 at 8:05pm
May 7, 2015 at 12:31pm
Hello booradley60,

I`m not sure if I understand you right but here is something that I put together:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

#include <stdio.h>
#define MAXLINE 1000
#define SAPACE  ' '


int countspaces(int offset, int tabsize)
{

   int spaces;
   spaces = tabsize - offset;
   return spaces;
   
}


int main()

{

char Buffer[MAXLINE];
int i, j, x;

for(i = 0; Buffer[i] != '\0'; ++i)
{
   j = countspaces(i, 8);
  
    while (( c = getchar() != '\n' )
      {
    
        for (x = 0; x < j)
          {
             putchar(SPACE);
           
          }
      }
}

}

Last edited on May 7, 2015 at 12:33pm
May 7, 2015 at 2:55pm
1
2
3
4
5
6
7
8
9
int SpacesToNextTabStop(int currentLinePos, int tabStopWidth)
{
    /*
    How many spaces?
    Modulo part gives us how far past the last tab stop we are.
    Subtract that distance from the tab width to figure out how far away the next one is
    */
    return (tabStopWidth - (currentLinePos % tabStopWidth));
}
To use this function, you must know the tab stop width (which is probably going to be a constant or some parameter you get from the user).

You must also know how far into the current line you are. Every time you get a character and print it, you must increment this counter. If you take a tab and turn it into spaces, you must increment this counter for every space you put in. When you hit a new line ('\n') you should reset the counter to 0.
1
2
3
4
5
6
7
8
9
        if(c == '\t') /*next char is a tab, we need to inject spaces*/
        {
            int numSpaces = SpacesToNextTabStop(currentLinePos, TAB_WIDTH);
            for(int i = 0; i < numSpaces; ++i)
            {
                putchar(' ');
                ++currentLinePos;
            }
        }
Last edited on May 7, 2015 at 2:57pm
May 7, 2015 at 4:46pm
I think that tabsize - offset;

and tabsize - (offset % tabsize);

do the same thing.
May 7, 2015 at 5:21pm
Up to the first tab stop they do. What if you've typed text into a line and gone beyond the first tab? The number of spaces you need to get to the next tab stop isn't a negative number, but if offset is greater than tabsize, then that's exactly what (tabsize - offset) will give you.
May 7, 2015 at 5:46pm
Well that suggests to reset offset every time a tab is encountered ; -)
May 7, 2015 at 6:01pm
Depends on how you interpret offset. If you want offset to be "How far am I from the last tab stop" then that would work. I was speaking of offset as "How far am I from the beginning of the line".
May 8, 2015 at 10:48am
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

#include <stdio.h>
#define SAPACE  ' '
#define TAB  '\t'

int countspaces(int offset, int tabsize)
{

  return tabsize - (offset % tabsize);
   
}


int main(void)

{
  
  int pos;

  while((c=getchar()) != EOF)
  {
    
    ++pos;
  
  if(c == TAB) 
        {
            int numSpaces = countspaces(pos, 5);
            for(int i = 0; i < numSpaces; ++i)
            {
                putchar(SPACE);
                ++pos;
            }
        }
        
    else if( c == '\n')
        {
         
          pos = 0;
          
        }
        
    else
      {
         putchar(c);
         ++pos;
      }
   }
  
}

Last edited on May 8, 2015 at 10:48am
May 8, 2015 at 12:48pm
Looks pretty good. 3 small things:
1. When you create pos on line 18, it would be a good idea to initialize it to zero.
2. Don't increment pos on line 23. You want to wait until after you've processed the character to increment pos, and it looks like in each case of your if-else structure you are indeed already doing that.
3. In the " c == '\n' " case, you probably should keep the newline character as part of the output. On line 37 you could say putchar(c); like you do in the 'else' case.
Topic archived. No new replies allowed.