In the below program, when we have 4 consecutive spaces, the following comparison will not be equal: (x / tabstop != (x + spaces) / tabstop). If we have, let's say, only 2 consecutive spaces, then the comparison will be equal. So we know to print a tab with 4 consecutive spaces and not print a tab otherwise. How do we know this kind of division comparison would work in every case?
#include <stdio.h>
#define TABSTOP 4
int main(void)
{
size_t spaces = 0;
int ch;
size_t x = 0; /* position in the line */
size_t tabstop = TABSTOP; /* get this from the command-line
* if you want to */
while ((ch = getchar()) != EOF)
{
if (ch == ' ')
{
spaces++;
}
elseif (spaces == 0) /* no space, just printing */
{
putchar(ch);
x++;
}
elseif (spaces == 1) /* just one space, never print a tab */
{
putchar(' ');
putchar(ch);
x += 2;
spaces = 0;
}
else
{
while (x / tabstop != (x + spaces) / tabstop)
/* are the spaces reaching behind the next tabstop ? */
{
putchar('\t');
x++;
spaces--;
while (x % tabstop != 0)
{
x++;
spaces--;
}
}
while (spaces > 0) /* the remaining ones are real space */
{
putchar(' ');
x++;
spaces--;
}
putchar(ch); /* now print the non-space char */
x++;
}
if (ch == '\n')
{
x = 0; /* reset line position */
}
}
return 0;
}
> when we have 4 consecutive spaces,
> the following comparison will not be equal: (x / tabstop != (x + spaces) / tabstop).
> If we have, let's say, only 2 consecutive spaces, then the comparison will be equal
wrong.
If spaces >= tabstop-x%tabstop the comparison would not be equal
If you surpass the marker, a TAB would be inserted (especial case if there is only one space)
Suppose tabstop=4, that is: there is a mark each 4 characters.
x%tabstop is how much you are past the last mark. By instance, if x=42, you are over 2 characters of the mark 40.
tabstop - x%tabstop would be how much you need to advance in order to reach the next mark. So, if x=42, you need to advance 2 characters to reach the mark 44.
(x / tabstop != (x + spaces) / tabstop)
Both sides would be equal if `x' and `x+spaces' are between the same marks [)
So x=42 is between the mark 40 and 44
Now add the spaces,
if spaces=1 -> x+spaces = 43. It's between marks 40 and 44 (same)
if spaces=2 -> x+spaces = 44. It's between marks 44 and 48 (different)
if spaces=3 -> x+spaces = 45. It's between marks 44 and 48 (different)
So you would want to know the number of spaces to reach the next mark,
that is tabstop - x%tabstop
If you reach the next mark, you need to insert a TAB