I'm teaching myself C and working through K&R. I'm doing exercise 1-20:
Write a Program entab that replaces strings of blanks by the minimum number of tabs and blanks to acheive the same spacing. Use the same tab stops as for detab.
I worked through this program myself, but was reviewing other solutions:
#include<stdio.h>
#define TABINC 8
int main(void)
{
int nb,pos,c;
nb = 0;
pos = 1;
while((c=getchar())!=EOF)
{
if( c == '\t')
{
nb = TABINC - (( pos - 1) % TABINC); // <---- How does this work
while( nb > 0)
{
putchar('#');
++pos;
--nb;
}
}
else if( c == '\n')
{
putchar(c);
pos = 1;
}
else
{
putchar(c);
++pos;
}
}
return 0;
}
I have difficulty understanding how this part works nb = TABINC - (( pos - 1) % TABINC);
. Can someone please explain what this is exactly doing step by step? Perhaps walk me through an example?
Thank you.
Consider the following input text:
\tone\ntwo\tthree\nsixteen\tseventeen\teighteen\n
This is what we want it to produce (tabs replaced with ···
):
Column: | | | |
123456789012345678901234567890123
Line: 1 ········one
2 two·····three
3 sixteen·seventeen·······eighteen
The number of spaces required for each tab character is always going to be a number from 1 to TABINC
(i.e., 8) inclusive. The tabs in the above example are expanded as follows:
Current Next tab No. spaces
column# position required
1 9 8
4 9 5
8 9 1
18 25 7
You should be able to see a pattern here. If we are already at a tab position (1, 9, 17, etc.), we need to add 8 spaces. And in general, if we are n
characters past a tab position (where 0 <= n <= 7
), then we need to add 8-n
spaces.
We can calculate n
easily:
n = (pos - 1) % 8
so nb
(the number of spaces we need to add) can simply be calculated as follows:
nb = 8 - n
Hence
nb = 8 - ((pos - 1) % 8)
Or, more generally,
nb = TABINC - ((pos - 1) % TABINC)