Program help

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?
Column may just mean spaces. for example, a tab could be the same as 4 spaces.
That was intelligent.

¿ Should I replace every tab by a single or two blanks ?
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
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
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
I think that tabsize - offset;

and tabsize - (offset % tabsize);

do the same thing.
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.
Well that suggests to reset offset every time a tab is encountered ; -)
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".
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
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.